use std::sync::{Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
pub fn read_lock<T>(lock: &RwLock<T>) -> RwLockReadGuard<'_, T> {
lock.read().unwrap_or_else(|e| e.into_inner())
}
pub fn write_lock<T>(lock: &RwLock<T>) -> RwLockWriteGuard<'_, T> {
lock.write().unwrap_or_else(|e| e.into_inner())
}
pub fn mutex_lock<T>(lock: &Mutex<T>) -> MutexGuard<'_, T> {
lock.lock().unwrap_or_else(|e| e.into_inner())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn helpers_recover_from_poisoned_locks() {
let rw = RwLock::new(1u32);
let _ = std::panic::catch_unwind(|| {
let _guard = crate::sync_guard::write_lock(&rw);
panic!("boom");
});
assert!(rw.is_poisoned());
assert_eq!(*read_lock(&rw), 1);
*write_lock(&rw) = 2;
assert_eq!(*read_lock(&rw), 2);
let m = Mutex::new(3u32);
let _ = std::panic::catch_unwind(|| {
let _guard = crate::sync_guard::mutex_lock(&m);
panic!("boom");
});
assert_eq!(*mutex_lock(&m), 3);
}
}