1
1
#[ cfg( all( test, not( target_os = "emscripten" ) ) ) ]
2
2
mod tests;
3
3
4
+ use super :: mutex as sys;
4
5
use crate :: cell:: UnsafeCell ;
5
- use crate :: marker:: PhantomPinned ;
6
6
use crate :: ops:: Deref ;
7
7
use crate :: panic:: { RefUnwindSafe , UnwindSafe } ;
8
- use crate :: pin:: Pin ;
9
8
use crate :: sync:: atomic:: { AtomicUsize , Ordering :: Relaxed } ;
10
- use crate :: sys:: locks as sys;
11
9
12
10
/// A re-entrant mutual exclusion
13
11
///
@@ -41,11 +39,10 @@ use crate::sys::locks as sys;
41
39
/// synchronization is left to the mutex, making relaxed memory ordering for
42
40
/// the `owner` field fine in all cases.
43
41
pub struct ReentrantMutex < T > {
44
- mutex : sys:: Mutex ,
42
+ mutex : sys:: MovableMutex ,
45
43
owner : AtomicUsize ,
46
44
lock_count : UnsafeCell < u32 > ,
47
45
data : T ,
48
- _pinned : PhantomPinned ,
49
46
}
50
47
51
48
unsafe impl < T : Send > Send for ReentrantMutex < T > { }
@@ -68,39 +65,22 @@ impl<T> RefUnwindSafe for ReentrantMutex<T> {}
68
65
/// guarded data.
69
66
#[ must_use = "if unused the ReentrantMutex will immediately unlock" ]
70
67
pub struct ReentrantMutexGuard < ' a , T : ' a > {
71
- lock : Pin < & ' a ReentrantMutex < T > > ,
68
+ lock : & ' a ReentrantMutex < T > ,
72
69
}
73
70
74
71
impl < T > !Send for ReentrantMutexGuard < ' _ , T > { }
75
72
76
73
impl < T > ReentrantMutex < T > {
77
74
/// Creates a new reentrant mutex in an unlocked state.
78
- ///
79
- /// # Unsafety
80
- ///
81
- /// This function is unsafe because it is required that `init` is called
82
- /// once this mutex is in its final resting place, and only then are the
83
- /// lock/unlock methods safe.
84
- pub const unsafe fn new ( t : T ) -> ReentrantMutex < T > {
75
+ pub const fn new ( t : T ) -> ReentrantMutex < T > {
85
76
ReentrantMutex {
86
- mutex : sys:: Mutex :: new ( ) ,
77
+ mutex : sys:: MovableMutex :: new ( ) ,
87
78
owner : AtomicUsize :: new ( 0 ) ,
88
79
lock_count : UnsafeCell :: new ( 0 ) ,
89
80
data : t,
90
- _pinned : PhantomPinned ,
91
81
}
92
82
}
93
83
94
- /// Initializes this mutex so it's ready for use.
95
- ///
96
- /// # Unsafety
97
- ///
98
- /// Unsafe to call more than once, and must be called after this will no
99
- /// longer move in memory.
100
- pub unsafe fn init ( self : Pin < & mut Self > ) {
101
- self . get_unchecked_mut ( ) . mutex . init ( )
102
- }
103
-
104
84
/// Acquires a mutex, blocking the current thread until it is able to do so.
105
85
///
106
86
/// This function will block the caller until it is available to acquire the mutex.
@@ -113,15 +93,14 @@ impl<T> ReentrantMutex<T> {
113
93
/// If another user of this mutex panicked while holding the mutex, then
114
94
/// this call will return failure if the mutex would otherwise be
115
95
/// acquired.
116
- pub fn lock ( self : Pin < & Self > ) -> ReentrantMutexGuard < ' _ , T > {
96
+ pub fn lock ( & self ) -> ReentrantMutexGuard < ' _ , T > {
117
97
let this_thread = current_thread_unique_ptr ( ) ;
118
- // Safety: We only touch lock_count when we own the lock,
119
- // and since self is pinned we can safely call the lock() on the mutex.
98
+ // Safety: We only touch lock_count when we own the lock.
120
99
unsafe {
121
100
if self . owner . load ( Relaxed ) == this_thread {
122
101
self . increment_lock_count ( ) ;
123
102
} else {
124
- self . mutex . lock ( ) ;
103
+ self . mutex . raw_lock ( ) ;
125
104
self . owner . store ( this_thread, Relaxed ) ;
126
105
debug_assert_eq ! ( * self . lock_count. get( ) , 0 ) ;
127
106
* self . lock_count . get ( ) = 1 ;
@@ -142,10 +121,9 @@ impl<T> ReentrantMutex<T> {
142
121
/// If another user of this mutex panicked while holding the mutex, then
143
122
/// this call will return failure if the mutex would otherwise be
144
123
/// acquired.
145
- pub fn try_lock ( self : Pin < & Self > ) -> Option < ReentrantMutexGuard < ' _ , T > > {
124
+ pub fn try_lock ( & self ) -> Option < ReentrantMutexGuard < ' _ , T > > {
146
125
let this_thread = current_thread_unique_ptr ( ) ;
147
- // Safety: We only touch lock_count when we own the lock,
148
- // and since self is pinned we can safely call the try_lock on the mutex.
126
+ // Safety: We only touch lock_count when we own the lock.
149
127
unsafe {
150
128
if self . owner . load ( Relaxed ) == this_thread {
151
129
self . increment_lock_count ( ) ;
@@ -179,12 +157,12 @@ impl<T> Deref for ReentrantMutexGuard<'_, T> {
179
157
impl < T > Drop for ReentrantMutexGuard < ' _ , T > {
180
158
#[ inline]
181
159
fn drop ( & mut self ) {
182
- // Safety: We own the lock, and the lock is pinned .
160
+ // Safety: We own the lock.
183
161
unsafe {
184
162
* self . lock . lock_count . get ( ) -= 1 ;
185
163
if * self . lock . lock_count . get ( ) == 0 {
186
164
self . lock . owner . store ( 0 , Relaxed ) ;
187
- self . lock . mutex . unlock ( ) ;
165
+ self . lock . mutex . raw_unlock ( ) ;
188
166
}
189
167
}
190
168
}
0 commit comments