@@ -25,6 +25,11 @@ mod mutex_impl {
25
25
pub fn lock ( & self ) -> MutexGuard < ' _ , T > {
26
26
self . 0 . lock ( )
27
27
}
28
+
29
+ #[ inline( always) ]
30
+ pub fn try_lock ( & self ) -> Option < MutexGuard < ' _ , T > > {
31
+ self . 0 . try_lock ( )
32
+ }
28
33
}
29
34
}
30
35
@@ -72,8 +77,12 @@ mod mutex_impl {
72
77
}
73
78
74
79
pub fn lock ( & self ) -> MutexGuard < ' _ , T > {
75
- // Detect if we are recursively taking out a lock on this mutex.
80
+ let ptr = self . detect_recursive_lock ( ) ;
81
+ MutexGuard ( self . 0 . lock ( ) , ptr)
82
+ }
76
83
84
+ /// Detect if we are recursively taking out a lock on this mutex.
85
+ fn detect_recursive_lock ( & self ) -> * const ( ) {
77
86
// use a pointer to the inner data as an id for this lock
78
87
let ptr = std:: ptr:: from_ref :: < parking_lot:: Mutex < _ > > ( & self . 0 ) . cast :: < ( ) > ( ) ;
79
88
@@ -82,7 +91,14 @@ mod mutex_impl {
82
91
held_locks. borrow_mut ( ) . insert ( ptr) ;
83
92
} ) ;
84
93
85
- MutexGuard ( self . 0 . lock ( ) , ptr)
94
+ ptr
95
+ }
96
+
97
+ pub fn try_lock ( & self ) -> Option < MutexGuard < ' _ , T > > {
98
+ self . 0 . try_lock ( ) . map ( |guard| {
99
+ let ptr = self . detect_recursive_lock ( ) ;
100
+ MutexGuard ( guard, ptr)
101
+ } )
86
102
}
87
103
88
104
#[ inline( always) ]
@@ -389,6 +405,16 @@ mod tests {
389
405
let _b = two. lock ( ) ;
390
406
}
391
407
408
+ #[ test]
409
+ fn try_lock ( ) {
410
+ let one = Mutex :: new ( ( ) ) ;
411
+ let _a = one. try_lock ( ) . expect ( "lockable" ) ;
412
+ let _b = one. try_lock ( ) ;
413
+ assert ! ( _b. is_none( ) ) ;
414
+ drop ( _a) ;
415
+ let _c = one. try_lock ( ) . expect ( "lockable again" ) ;
416
+ }
417
+
392
418
#[ test]
393
419
fn lock_multiple_threads ( ) {
394
420
use std:: sync:: Arc ;
0 commit comments