@@ -74,7 +74,9 @@ impl MutexMetadata {
74
74
}
75
75
}
76
76
77
- fn pre_lock ( this : & Arc < MutexMetadata > , read : bool ) {
77
+ // Returns whether we were a recursive lock (only relevant for read)
78
+ fn _pre_lock ( this : & Arc < MutexMetadata > , read : bool ) -> bool {
79
+ let mut inserted = false ;
78
80
MUTEXES_HELD . with ( |held| {
79
81
// For each mutex which is currently locked, check that no mutex's locked-before
80
82
// set includes the mutex we're about to lock, which would imply a lockorder
@@ -101,9 +103,14 @@ impl MutexMetadata {
101
103
this. locked_before . lock ( ) . unwrap ( ) . insert ( Arc :: clone ( locked) ) ;
102
104
}
103
105
held. borrow_mut ( ) . insert ( Arc :: clone ( this) ) ;
106
+ inserted = true ;
104
107
} ) ;
108
+ inserted
105
109
}
106
110
111
+ fn pre_lock ( this : & Arc < MutexMetadata > ) { Self :: _pre_lock ( this, false ) ; }
112
+ fn pre_read_lock ( this : & Arc < MutexMetadata > ) -> bool { Self :: _pre_lock ( this, true ) }
113
+
107
114
fn try_locked ( this : & Arc < MutexMetadata > ) {
108
115
MUTEXES_HELD . with ( |held| {
109
116
// Since a try-lock will simply fail if the lock is held already, we do not
@@ -167,7 +174,7 @@ impl<T> Mutex<T> {
167
174
}
168
175
169
176
pub fn lock < ' a > ( & ' a self ) -> LockResult < MutexGuard < ' a , T > > {
170
- MutexMetadata :: pre_lock ( & self . deps , false ) ;
177
+ MutexMetadata :: pre_lock ( & self . deps ) ;
171
178
self . inner . lock ( ) . map ( |lock| MutexGuard { mutex : self , lock } ) . map_err ( |_| ( ) )
172
179
}
173
180
@@ -187,6 +194,7 @@ pub struct RwLock<T: Sized> {
187
194
188
195
pub struct RwLockReadGuard < ' a , T : Sized + ' a > {
189
196
mutex : & ' a RwLock < T > ,
197
+ first_lock : bool ,
190
198
lock : StdRwLockReadGuard < ' a , T > ,
191
199
}
192
200
@@ -205,6 +213,7 @@ impl<T: Sized> Deref for RwLockReadGuard<'_, T> {
205
213
206
214
impl < T : Sized > Drop for RwLockReadGuard < ' _ , T > {
207
215
fn drop ( & mut self ) {
216
+ if !self . first_lock { return ; }
208
217
MUTEXES_HELD . with ( |held| {
209
218
held. borrow_mut ( ) . remove ( & self . mutex . deps ) ;
210
219
} ) ;
@@ -239,12 +248,12 @@ impl<T> RwLock<T> {
239
248
}
240
249
241
250
pub fn read < ' a > ( & ' a self ) -> LockResult < RwLockReadGuard < ' a , T > > {
242
- MutexMetadata :: pre_lock ( & self . deps , true ) ;
243
- self . inner . read ( ) . map ( |lock| RwLockReadGuard { mutex : self , lock } ) . map_err ( |_| ( ) )
251
+ let first_lock = MutexMetadata :: pre_read_lock ( & self . deps ) ;
252
+ self . inner . read ( ) . map ( |lock| RwLockReadGuard { mutex : self , lock, first_lock } ) . map_err ( |_| ( ) )
244
253
}
245
254
246
255
pub fn write < ' a > ( & ' a self ) -> LockResult < RwLockWriteGuard < ' a , T > > {
247
- MutexMetadata :: pre_lock ( & self . deps , false ) ;
256
+ MutexMetadata :: pre_lock ( & self . deps ) ;
248
257
self . inner . write ( ) . map ( |lock| RwLockWriteGuard { mutex : self , lock } ) . map_err ( |_| ( ) )
249
258
}
250
259
0 commit comments