Skip to content

Commit e0fefc2

Browse files
committed
ex: Remove unsafe code from mutex example
This brings in the try-lock dependency. Signed-off-by: John Nunley <[email protected]>
1 parent 68be528 commit e0fefc2

File tree

2 files changed

+9
-27
lines changed

2 files changed

+9
-27
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ optional = true
3535

3636
[dev-dependencies]
3737
futures-lite = "2.0.0"
38+
try-lock = "0.2.5"
3839
waker-fn = "1"
3940

4041
[dev-dependencies.criterion]

examples/mutex.rs

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,21 @@
66
mod example {
77
#![allow(dead_code)]
88

9-
use std::cell::UnsafeCell;
109
use std::ops::{Deref, DerefMut};
11-
use std::sync::atomic::{AtomicBool, Ordering};
1210
use std::sync::{mpsc, Arc};
1311
use std::thread;
1412
use std::time::{Duration, Instant};
1513

1614
use event_listener::{listener, Event, Listener};
15+
use try_lock::{Locked, TryLock};
1716

1817
/// A simple mutex.
1918
struct Mutex<T> {
20-
/// Set to `true` when the mutex is locked.
21-
locked: AtomicBool,
22-
2319
/// Blocked lock operations.
2420
lock_ops: Event,
2521

26-
/// The inner protected data.
27-
data: UnsafeCell<T>,
22+
/// The inner non-blocking mutex.
23+
data: TryLock<T>,
2824
}
2925

3026
unsafe impl<T: Send> Send for Mutex<T> {}
@@ -34,19 +30,14 @@ mod example {
3430
/// Creates a mutex.
3531
fn new(t: T) -> Mutex<T> {
3632
Mutex {
37-
locked: AtomicBool::new(false),
3833
lock_ops: Event::new(),
39-
data: UnsafeCell::new(t),
34+
data: TryLock::new(t),
4035
}
4136
}
4237

4338
/// Attempts to acquire a lock.
4439
fn try_lock(&self) -> Option<MutexGuard<'_, T>> {
45-
if !self.locked.swap(true, Ordering::Acquire) {
46-
Some(MutexGuard(self))
47-
} else {
48-
None
49-
}
40+
self.data.try_lock().map(MutexGuard)
5041
}
5142

5243
/// Blocks until a lock is acquired.
@@ -116,29 +107,19 @@ mod example {
116107
}
117108

118109
/// A guard holding a lock.
119-
struct MutexGuard<'a, T>(&'a Mutex<T>);
120-
121-
unsafe impl<T: Send> Send for MutexGuard<'_, T> {}
122-
unsafe impl<T: Sync> Sync for MutexGuard<'_, T> {}
123-
124-
impl<T> Drop for MutexGuard<'_, T> {
125-
fn drop(&mut self) {
126-
self.0.locked.store(false, Ordering::Release);
127-
self.0.lock_ops.notify(1);
128-
}
129-
}
110+
struct MutexGuard<'a, T>(Locked<'a, T>);
130111

131112
impl<T> Deref for MutexGuard<'_, T> {
132113
type Target = T;
133114

134115
fn deref(&self) -> &T {
135-
unsafe { &*self.0.data.get() }
116+
&self.0
136117
}
137118
}
138119

139120
impl<T> DerefMut for MutexGuard<'_, T> {
140121
fn deref_mut(&mut self) -> &mut T {
141-
unsafe { &mut *self.0.data.get() }
122+
&mut self.0
142123
}
143124
}
144125

0 commit comments

Comments
 (0)