#![cfg(loom)] use std::sync::atomic::Ordering; mod fixture; use fixture::TrackNotify; use fixture::Unit; #[test] fn new_and_delete() { loom::model(|| { let (tx, rx) = splitrc::new(Unit); drop(tx); drop(rx); }) } #[test] fn drop_rx_notifies() { loom::model(|| { let (tx, rx) = splitrc::new(TrackNotify::default()); let rx2 = rx.clone(); drop(rx); drop(rx2); assert!(!tx.tx_did_drop.load(Ordering::Acquire)); assert!(tx.rx_did_drop.load(Ordering::Acquire)); }) } #[test] fn drop_tx_notifies() { loom::model(|| { let (tx, rx) = splitrc::new(TrackNotify::default()); let tx2 = tx.clone(); drop(tx); drop(tx2); assert!(rx.tx_did_drop.load(Ordering::Acquire)); assert!(!rx.rx_did_drop.load(Ordering::Acquire)); }) } #[test] fn racing_drop() { loom::model(|| { let (tx, rx) = splitrc::new(TrackNotify::default()); loom::thread::spawn(move || tx.access()); loom::thread::spawn(move || rx.access()); }) } #[test] fn racing_drop_two_tx() { loom::model(|| { let (tx1, rx) = splitrc::new(TrackNotify::default()); let tx2 = tx1.clone(); drop(rx); loom::thread::spawn(move || tx1.access()); loom::thread::spawn(move || tx2.access()); }) } #[test] fn racing_drop_two_rx() { loom::model(|| { let (tx, rx1) = splitrc::new(TrackNotify::default()); let rx2 = rx1.clone(); drop(tx); loom::thread::spawn(move || rx1.access()); loom::thread::spawn(move || rx2.access()); }) } #[test] #[ignore = "very slow"] fn racing_drop_4_threads() { loom::model(|| { let (tx1, rx1) = splitrc::new(TrackNotify::default()); let tx2 = tx1.clone(); let rx2 = rx1.clone(); loom::thread::spawn(move || tx1.access()); loom::thread::spawn(move || tx2.access()); loom::thread::spawn(move || rx1.access()); loom::thread::spawn(move || rx2.access()); }) }