ex: Remove unsafe code from mutex example

This brings in the try-lock dependency.

Signed-off-by: John Nunley <dev@notgull.net>
This commit is contained in:
John Nunley 2023-12-19 19:37:27 -08:00 committed by John Nunley
parent 68be5281d7
commit e0fefc28b1
2 changed files with 9 additions and 27 deletions

View File

@ -35,6 +35,7 @@ optional = true
[dev-dependencies]
futures-lite = "2.0.0"
try-lock = "0.2.5"
waker-fn = "1"
[dev-dependencies.criterion]

View File

@ -6,25 +6,21 @@
mod example {
#![allow(dead_code)]
use std::cell::UnsafeCell;
use std::ops::{Deref, DerefMut};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{mpsc, Arc};
use std::thread;
use std::time::{Duration, Instant};
use event_listener::{listener, Event, Listener};
use try_lock::{Locked, TryLock};
/// A simple mutex.
struct Mutex<T> {
/// Set to `true` when the mutex is locked.
locked: AtomicBool,
/// Blocked lock operations.
lock_ops: Event,
/// The inner protected data.
data: UnsafeCell<T>,
/// The inner non-blocking mutex.
data: TryLock<T>,
}
unsafe impl<T: Send> Send for Mutex<T> {}
@ -34,19 +30,14 @@ mod example {
/// Creates a mutex.
fn new(t: T) -> Mutex<T> {
Mutex {
locked: AtomicBool::new(false),
lock_ops: Event::new(),
data: UnsafeCell::new(t),
data: TryLock::new(t),
}
}
/// Attempts to acquire a lock.
fn try_lock(&self) -> Option<MutexGuard<'_, T>> {
if !self.locked.swap(true, Ordering::Acquire) {
Some(MutexGuard(self))
} else {
None
}
self.data.try_lock().map(MutexGuard)
}
/// Blocks until a lock is acquired.
@ -116,29 +107,19 @@ mod example {
}
/// A guard holding a lock.
struct MutexGuard<'a, T>(&'a Mutex<T>);
unsafe impl<T: Send> Send for MutexGuard<'_, T> {}
unsafe impl<T: Sync> Sync for MutexGuard<'_, T> {}
impl<T> Drop for MutexGuard<'_, T> {
fn drop(&mut self) {
self.0.locked.store(false, Ordering::Release);
self.0.lock_ops.notify(1);
}
}
struct MutexGuard<'a, T>(Locked<'a, T>);
impl<T> Deref for MutexGuard<'_, T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.0.data.get() }
&self.0
}
}
impl<T> DerefMut for MutexGuard<'_, T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *self.0.data.get() }
&mut self.0
}
}