tuwunel_core/utils/mutex.rs
1//! Poison-tolerant locking for std mutexes.
2//!
3//! `Mutex::lock` reports an error once any holder has panicked; the extension
4//! here takes the lock regardless.
5
6use std::sync::{Mutex, MutexGuard, PoisonError};
7
8#[cfg(test)]
9mod tests;
10
11/// Locking for a std mutex whose data no holder can leave half-updated.
12///
13/// For such data the poison carries no information, so code that must not
14/// panic, such as a drop running during an unwind, can still take the lock.
15pub trait MutexExt<T: ?Sized> {
16 /// Take the lock, adopting a poisoned one.
17 ///
18 /// The poison only records that some holder panicked, so adopting it is
19 /// correct only where no holder can panic midway through an update. A
20 /// thread relocking a mutex it already holds may still panic or deadlock,
21 /// as under `lock`.
22 fn lock_adopting(&self) -> MutexGuard<'_, T>;
23}
24
25impl<T: ?Sized> MutexExt<T> for Mutex<T> {
26 #[inline]
27 fn lock_adopting(&self) -> MutexGuard<'_, T> {
28 self.lock()
29 .unwrap_or_else(PoisonError::into_inner)
30 }
31}