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