From e0fefc28b12097e66fb9fd31b1175f82bdbcc7b1 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Tue, 19 Dec 2023 19:37:27 -0800 Subject: [PATCH] ex: Remove unsafe code from mutex example This brings in the try-lock dependency. Signed-off-by: John Nunley --- Cargo.toml | 1 + examples/mutex.rs | 35 ++++++++--------------------------- 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d98f878..1a0d66e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ optional = true [dev-dependencies] futures-lite = "2.0.0" +try-lock = "0.2.5" waker-fn = "1" [dev-dependencies.criterion] diff --git a/examples/mutex.rs b/examples/mutex.rs index 6976cb7..30fbe66 100644 --- a/examples/mutex.rs +++ b/examples/mutex.rs @@ -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 { - /// Set to `true` when the mutex is locked. - locked: AtomicBool, - /// Blocked lock operations. lock_ops: Event, - /// The inner protected data. - data: UnsafeCell, + /// The inner non-blocking mutex. + data: TryLock, } unsafe impl Send for Mutex {} @@ -34,19 +30,14 @@ mod example { /// Creates a mutex. fn new(t: T) -> Mutex { 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> { - 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); - - unsafe impl Send for MutexGuard<'_, T> {} - unsafe impl Sync for MutexGuard<'_, T> {} - - impl 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 Deref for MutexGuard<'_, T> { type Target = T; fn deref(&self) -> &T { - unsafe { &*self.0.data.get() } + &self.0 } } impl DerefMut for MutexGuard<'_, T> { fn deref_mut(&mut self) -> &mut T { - unsafe { &mut *self.0.data.get() } + &mut self.0 } }