@@ -5,15 +5,16 @@ use core::time::Duration;
55
66use std:: cell:: RefCell ;
77
8- use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
9- use std:: sync:: Condvar as StdCondvar ;
10- use std:: sync:: Mutex as StdMutex ;
11- use std:: sync:: MutexGuard as StdMutexGuard ;
8+ use std:: sync:: atomic:: { AtomicBool , AtomicUsize , Ordering } ;
129use std:: sync:: RwLock as StdRwLock ;
1310use std:: sync:: RwLockReadGuard as StdRwLockReadGuard ;
1411use std:: sync:: RwLockWriteGuard as StdRwLockWriteGuard ;
1512
16- pub use std:: sync:: WaitTimeoutResult ;
13+ use parking_lot:: Condvar as StdCondvar ;
14+ use parking_lot:: Mutex as StdMutex ;
15+ use parking_lot:: MutexGuard as StdMutexGuard ;
16+
17+ pub use parking_lot:: WaitTimeoutResult ;
1718
1819use crate :: prelude:: * ;
1920
@@ -46,21 +47,19 @@ impl Condvar {
4647 & ' a self , guard : MutexGuard < ' a , T > , condition : F ,
4748 ) -> LockResult < MutexGuard < ' a , T > > {
4849 let mutex: & ' a Mutex < T > = guard. mutex ;
49- self . inner
50- . wait_while ( guard. into_inner ( ) , condition)
51- . map ( |lock| MutexGuard { mutex, lock } )
52- . map_err ( |_| ( ) )
50+ let mut lock = guard. into_inner ( ) ;
51+ self . inner . wait_while ( & mut lock, condition) ;
52+ Ok ( MutexGuard { mutex, lock : Some ( lock) } )
5353 }
5454
5555 #[ allow( unused) ]
5656 pub fn wait_timeout_while < ' a , T , F : FnMut ( & mut T ) -> bool > (
5757 & ' a self , guard : MutexGuard < ' a , T > , dur : Duration , condition : F ,
5858 ) -> LockResult < ( MutexGuard < ' a , T > , WaitTimeoutResult ) > {
5959 let mutex = guard. mutex ;
60- self . inner
61- . wait_timeout_while ( guard. into_inner ( ) , dur, condition)
62- . map_err ( |_| ( ) )
63- . map ( |( lock, e) | ( MutexGuard { mutex, lock } , e) )
60+ let mut lock = guard. into_inner ( ) ;
61+ let e = self . inner . wait_while_for ( & mut lock, condition, dur) ;
62+ Ok ( ( MutexGuard { mutex, lock : Some ( lock) } , e) )
6463 }
6564
6665 pub fn notify_all ( & self ) {
@@ -150,7 +149,7 @@ impl LockMetadata {
150149 LOCKS_INIT . call_once ( || unsafe {
151150 LOCKS = Some ( StdMutex :: new ( new_hash_map ( ) ) ) ;
152151 } ) ;
153- let mut locks = unsafe { LOCKS . as_ref ( ) } . unwrap ( ) . lock ( ) . unwrap ( ) ;
152+ let mut locks = unsafe { LOCKS . as_ref ( ) } . unwrap ( ) . lock ( ) ;
154153 match locks. entry ( lock_constr_location) {
155154 hash_map:: Entry :: Occupied ( e) => {
156155 assert_eq ! ( lock_constr_colno,
@@ -185,7 +184,7 @@ impl LockMetadata {
185184 }
186185 }
187186 for ( _locked_idx, locked) in held. borrow ( ) . iter ( ) {
188- for ( locked_dep_idx, _locked_dep) in locked. locked_before . lock ( ) . unwrap ( ) . iter ( ) {
187+ for ( locked_dep_idx, _locked_dep) in locked. locked_before . lock ( ) . iter ( ) {
189188 let is_dep_this_lock = * locked_dep_idx == this. lock_idx ;
190189 let has_same_construction = * locked_dep_idx == locked. lock_idx ;
191190 if is_dep_this_lock && !has_same_construction {
@@ -210,7 +209,7 @@ impl LockMetadata {
210209 }
211210 }
212211 // Insert any already-held locks in our locked-before set.
213- let mut locked_before = this. locked_before . lock ( ) . unwrap ( ) ;
212+ let mut locked_before = this. locked_before . lock ( ) ;
214213 if !locked_before. contains_key ( & locked. lock_idx ) {
215214 let lockdep = LockDep { lock : Arc :: clone ( locked) , _lockdep_trace : Backtrace :: new ( ) } ;
216215 locked_before. insert ( lockdep. lock . lock_idx , lockdep) ;
@@ -237,7 +236,7 @@ impl LockMetadata {
237236 // Since a try-lock will simply fail if the lock is held already, we do not
238237 // consider try-locks to ever generate lockorder inversions. However, if a try-lock
239238 // succeeds, we do consider it to have created lockorder dependencies.
240- let mut locked_before = this. locked_before . lock ( ) . unwrap ( ) ;
239+ let mut locked_before = this. locked_before . lock ( ) ;
241240 for ( locked_idx, locked) in held. borrow ( ) . iter ( ) {
242241 if !locked_before. contains_key ( locked_idx) {
243242 let lockdep =
@@ -252,11 +251,17 @@ impl LockMetadata {
252251
253252pub struct Mutex < T : Sized > {
254253 inner : StdMutex < T > ,
254+ poisoned : AtomicBool ,
255255 deps : Arc < LockMetadata > ,
256256}
257+
257258impl < T : Sized > Mutex < T > {
258259 pub ( crate ) fn into_inner ( self ) -> LockResult < T > {
259- self . inner . into_inner ( ) . map_err ( |_| ( ) )
260+ if self . poisoned . load ( Ordering :: Acquire ) {
261+ Err ( ( ) )
262+ } else {
263+ Ok ( self . inner . into_inner ( ) )
264+ }
260265 }
261266}
262267
@@ -278,14 +283,14 @@ impl<T: Sized + fmt::Debug> fmt::Debug for Mutex<T> {
278283#[ must_use = "if unused the Mutex will immediately unlock" ]
279284pub struct MutexGuard < ' a , T : Sized + ' a > {
280285 mutex : & ' a Mutex < T > ,
281- lock : StdMutexGuard < ' a , T > ,
286+ lock : Option < StdMutexGuard < ' a , T > > ,
282287}
283288
284289impl < ' a , T : Sized > MutexGuard < ' a , T > {
285290 fn into_inner ( self ) -> StdMutexGuard < ' a , T > {
286291 // Somewhat unclear why we cannot move out of self.lock, but doing so gets E0509.
287292 unsafe {
288- let v: StdMutexGuard < ' a , T > = std:: ptr:: read ( & self . lock ) ;
293+ let v: StdMutexGuard < ' a , T > = std:: ptr:: read ( self . lock . as_ref ( ) . unwrap ( ) ) ;
289294 std:: mem:: forget ( self ) ;
290295 v
291296 }
@@ -297,44 +302,63 @@ impl<T: Sized> Drop for MutexGuard<'_, T> {
297302 LOCKS_HELD . with ( |held| {
298303 held. borrow_mut ( ) . remove ( & self . mutex . deps . lock_idx ) ;
299304 } ) ;
305+ if std:: thread:: panicking ( ) {
306+ self . mutex . poisoned . store ( true , Ordering :: Release ) ;
307+ }
308+ StdMutexGuard :: unlock_fair ( self . lock . take ( ) . unwrap ( ) ) ;
300309 }
301310}
302311
303312impl < T : Sized > Deref for MutexGuard < ' _ , T > {
304313 type Target = T ;
305314
306315 fn deref ( & self ) -> & T {
307- & self . lock . deref ( )
316+ & self . lock . as_ref ( ) . unwrap ( ) . deref ( )
308317 }
309318}
310319
311320impl < T : Sized > DerefMut for MutexGuard < ' _ , T > {
312321 fn deref_mut ( & mut self ) -> & mut T {
313- self . lock . deref_mut ( )
322+ self . lock . as_mut ( ) . unwrap ( ) . deref_mut ( )
314323 }
315324}
316325
317326impl < T > Mutex < T > {
318327 pub fn new ( inner : T ) -> Mutex < T > {
319- Mutex { inner : StdMutex :: new ( inner) , deps : LockMetadata :: new ( ) }
328+ Mutex {
329+ inner : StdMutex :: new ( inner) ,
330+ poisoned : AtomicBool :: new ( false ) ,
331+ deps : LockMetadata :: new ( ) ,
332+ }
320333 }
321334
322335 pub fn lock < ' a > ( & ' a self ) -> LockResult < MutexGuard < ' a , T > > {
323336 LockMetadata :: pre_lock ( & self . deps , false ) ;
324- self . inner . lock ( ) . map ( |lock| MutexGuard { mutex : self , lock } ) . map_err ( |_| ( ) )
337+ let lock = self . inner . lock ( ) ;
338+ if self . poisoned . load ( Ordering :: Acquire ) {
339+ Err ( ( ) )
340+ } else {
341+ Ok ( MutexGuard { mutex : self , lock : Some ( lock) } )
342+ }
325343 }
326344
327345 pub fn try_lock < ' a > ( & ' a self ) -> LockResult < MutexGuard < ' a , T > > {
328- let res =
329- self . inner . try_lock ( ) . map ( |lock| MutexGuard { mutex : self , lock } ) . map_err ( |_| ( ) ) ;
346+ let res = self . inner . try_lock ( ) . ok_or ( ( ) ) ;
330347 if res. is_ok ( ) {
348+ if self . poisoned . load ( Ordering :: Acquire ) {
349+ return Err ( ( ) ) ;
350+ }
331351 LockMetadata :: try_locked ( & self . deps ) ;
332352 }
333- res
353+ res. map ( |lock| MutexGuard { mutex : self , lock : Some ( lock ) } )
334354 }
335355
336356 pub fn get_mut < ' a > ( & ' a mut self ) -> LockResult < & ' a mut T > {
337- self . inner . get_mut ( ) . map_err ( |_| ( ) )
357+ if self . poisoned . load ( Ordering :: Acquire ) {
358+ Err ( ( ) )
359+ } else {
360+ Ok ( self . inner . get_mut ( ) )
361+ }
338362 }
339363}
340364
@@ -345,9 +369,10 @@ impl<'a, T: 'a> LockTestExt<'a> for Mutex<T> {
345369 }
346370 type ExclLock = MutexGuard < ' a , T > ;
347371 #[ inline]
348- fn unsafe_well_ordered_double_lock_self ( & ' a self ) -> MutexGuard < T > {
372+ fn unsafe_well_ordered_double_lock_self ( & ' a self ) -> MutexGuard < ' a , T > {
349373 LockMetadata :: pre_lock ( & self . deps , true ) ;
350- self . inner . lock ( ) . map ( |lock| MutexGuard { mutex : self , lock } ) . unwrap ( )
374+ let lock = self . inner . lock ( ) ;
375+ MutexGuard { mutex : self , lock : Some ( lock) }
351376 }
352377}
353378
0 commit comments