use loom::sync::{Arc, RwLock, TryLockResult}; use loom::thread; use std::rc::Rc; use std::sync::TryLockError; #[test] fn rwlock_read_one() { loom::model(|| { let lock = Arc::new(RwLock::new(1)); let c_lock = lock.clone(); let n = lock.read().unwrap(); assert_eq!(*n, 1); thread::spawn(move || { let r = c_lock.read(); assert!(r.is_ok()); }) .join() .unwrap(); }); } #[test] fn rwlock_read_two_write_one() { loom::model(|| { let lock = Arc::new(RwLock::new(1)); for _ in 0..2 { let lock = lock.clone(); thread::spawn(move || { let _l = lock.read().unwrap(); thread::yield_now(); }); } let _l = lock.write().unwrap(); thread::yield_now(); }); } #[test] fn rwlock_write_three() { loom::model(|| { let lock = Arc::new(RwLock::new(1)); for _ in 0..2 { let lock = lock.clone(); thread::spawn(move || { let _l = lock.write().unwrap(); thread::yield_now(); }); } let _l = lock.write().unwrap(); thread::yield_now(); }); } #[test] fn rwlock_write_then_try_write() { loom::model(|| { let lock = Arc::new(RwLock::new(1)); let _l1 = lock.write().unwrap(); assert!(matches!( lock.try_write(), TryLockResult::Err(TryLockError::WouldBlock) )); }); } #[test] fn rwlock_write_then_try_read() { loom::model(|| { let lock = Arc::new(RwLock::new(1)); let _l1 = lock.write().unwrap(); assert!(matches!( lock.try_read(), TryLockResult::Err(TryLockError::WouldBlock) )); }); } #[test] fn rwlock_read_then_try_write() { loom::model(|| { let lock = Arc::new(RwLock::new(1)); let _l1 = lock.write().unwrap(); assert!(matches!( lock.try_write(), TryLockResult::Err(TryLockError::WouldBlock) )); }); } #[test] fn rwlock_try_read() { loom::model(|| { let lock = RwLock::new(1); match lock.try_read() { Ok(n) => assert_eq!(*n, 1), Err(_) => unreachable!(), }; }); } #[test] fn rwlock_write() { loom::model(|| { let lock = RwLock::new(1); let mut n = lock.write().unwrap(); *n = 2; assert!(lock.try_read().is_err()); }); } #[test] fn rwlock_try_write() { loom::model(|| { let lock = RwLock::new(1); let n = lock.read().unwrap(); assert_eq!(*n, 1); assert!(lock.try_write().is_err()); }); } #[test] fn rwlock_into_inner() { loom::model(|| { let lock = Rc::new(RwLock::new(0)); let ths: Vec<_> = (0..2) .map(|_| { let lock = lock.clone(); thread::spawn(move || { *lock.write().unwrap() += 1; }) }) .collect(); for th in ths { th.join().unwrap(); } let lock = Rc::try_unwrap(lock).unwrap().into_inner().unwrap(); assert_eq!(lock, 2); }) }