1use std::sync::{Mutex, MutexGuard, PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard};
4
5pub fn lock<T>(mutex: &Mutex<T>) -> MutexGuard<'_, T> {
7 mutex.lock().unwrap_or_else(PoisonError::into_inner)
8}
9
10pub fn read<T>(lock: &RwLock<T>) -> RwLockReadGuard<'_, T> {
12 lock.read().unwrap_or_else(PoisonError::into_inner)
13}
14
15pub fn write<T>(lock: &RwLock<T>) -> RwLockWriteGuard<'_, T> {
17 lock.write().unwrap_or_else(PoisonError::into_inner)
18}
19
20#[cfg(test)]
21mod tests {
22 use super::*;
23
24 #[test]
25 fn recovers_poisoned_rw_locks() {
26 let lock = RwLock::new(1);
27 let _ = std::panic::catch_unwind(|| {
28 let _guard = lock.write();
29 panic!("poison");
30 });
31 assert!(lock.is_poisoned());
32 *write(&lock) += 1;
33 assert_eq!(*read(&lock), 2);
34 }
35}