Skip to content

Commit e4bdb1e

Browse files
committed
Add support for 'try_lock' (both with/without deadlock_detection).
1 parent 66efb19 commit e4bdb1e

File tree

1 file changed

+28
-2
lines changed

1 file changed

+28
-2
lines changed

crates/epaint/src/mutex.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ mod mutex_impl {
2525
pub fn lock(&self) -> MutexGuard<'_, T> {
2626
self.0.lock()
2727
}
28+
29+
#[inline(always)]
30+
pub fn try_lock(&self) -> Option<MutexGuard<'_, T>> {
31+
self.0.try_lock()
32+
}
2833
}
2934
}
3035

@@ -72,8 +77,12 @@ mod mutex_impl {
7277
}
7378

7479
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+
}
7683

84+
/// Detect if we are recursively taking out a lock on this mutex.
85+
fn detect_recursive_lock(&self) -> *const () {
7786
// use a pointer to the inner data as an id for this lock
7887
let ptr = std::ptr::from_ref::<parking_lot::Mutex<_>>(&self.0).cast::<()>();
7988

@@ -82,7 +91,14 @@ mod mutex_impl {
8291
held_locks.borrow_mut().insert(ptr);
8392
});
8493

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+
})
86102
}
87103

88104
#[inline(always)]
@@ -389,6 +405,16 @@ mod tests {
389405
let _b = two.lock();
390406
}
391407

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+
392418
#[test]
393419
fn lock_multiple_threads() {
394420
use std::sync::Arc;

0 commit comments

Comments
 (0)