Skip to main content

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}