microscope_memory/
sync_guard.rs1use std::sync::{Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
9
10pub fn read_lock<T>(lock: &RwLock<T>) -> RwLockReadGuard<'_, T> {
12 lock.read().unwrap_or_else(|e| e.into_inner())
13}
14
15pub fn write_lock<T>(lock: &RwLock<T>) -> RwLockWriteGuard<'_, T> {
17 lock.write().unwrap_or_else(|e| e.into_inner())
18}
19
20pub fn mutex_lock<T>(lock: &Mutex<T>) -> MutexGuard<'_, T> {
22 lock.lock().unwrap_or_else(|e| e.into_inner())
23}
24
25#[cfg(test)]
26mod tests {
27 use super::*;
28
29 #[test]
30 fn helpers_recover_from_poisoned_locks() {
31 let rw = RwLock::new(1u32);
32 let _ = std::panic::catch_unwind(|| {
33 let _guard = crate::sync_guard::write_lock(&rw);
34 panic!("boom");
35 });
36 assert!(rw.is_poisoned());
37 assert_eq!(*read_lock(&rw), 1);
38 *write_lock(&rw) = 2;
39 assert_eq!(*read_lock(&rw), 2);
40
41 let m = Mutex::new(3u32);
42 let _ = std::panic::catch_unwind(|| {
43 let _guard = crate::sync_guard::mutex_lock(&m);
44 panic!("boom");
45 });
46 assert_eq!(*mutex_lock(&m), 3);
47 }
48}