| use crate::sync::watch; |
| |
| use loom::future::block_on; |
| use loom::thread; |
| use std::sync::Arc; |
| |
| #[test] |
| fn smoke() { |
| loom::model(|| { |
| let (tx, mut rx1) = watch::channel(1); |
| let mut rx2 = rx1.clone(); |
| let mut rx3 = rx1.clone(); |
| let mut rx4 = rx1.clone(); |
| let mut rx5 = rx1.clone(); |
| |
| let th = thread::spawn(move || { |
| tx.send(2).unwrap(); |
| }); |
| |
| block_on(rx1.changed()).unwrap(); |
| assert_eq!(*rx1.borrow(), 2); |
| |
| block_on(rx2.changed()).unwrap(); |
| assert_eq!(*rx2.borrow(), 2); |
| |
| block_on(rx3.changed()).unwrap(); |
| assert_eq!(*rx3.borrow(), 2); |
| |
| block_on(rx4.changed()).unwrap(); |
| assert_eq!(*rx4.borrow(), 2); |
| |
| block_on(rx5.changed()).unwrap(); |
| assert_eq!(*rx5.borrow(), 2); |
| |
| th.join().unwrap(); |
| }) |
| } |
| |
| #[test] |
| fn wait_for_test() { |
| loom::model(move || { |
| let (tx, mut rx) = watch::channel(false); |
| |
| let tx_arc = Arc::new(tx); |
| let tx1 = tx_arc.clone(); |
| let tx2 = tx_arc.clone(); |
| |
| let th1 = thread::spawn(move || { |
| for _ in 0..2 { |
| tx1.send_modify(|_x| {}); |
| } |
| }); |
| |
| let th2 = thread::spawn(move || { |
| tx2.send(true).unwrap(); |
| }); |
| |
| assert_eq!(*block_on(rx.wait_for(|x| *x)).unwrap(), true); |
| |
| th1.join().unwrap(); |
| th2.join().unwrap(); |
| }); |
| } |
| |
| #[test] |
| fn wait_for_returns_correct_value() { |
| loom::model(move || { |
| let (tx, mut rx) = watch::channel(0); |
| |
| let jh = thread::spawn(move || { |
| tx.send(1).unwrap(); |
| tx.send(2).unwrap(); |
| tx.send(3).unwrap(); |
| }); |
| |
| // Stop at the first value we are called at. |
| let mut stopped_at = usize::MAX; |
| let returned = *block_on(rx.wait_for(|x| { |
| stopped_at = *x; |
| true |
| })) |
| .unwrap(); |
| |
| // Check that it returned the same value as the one we returned |
| // `true` for. |
| assert_eq!(stopped_at, returned); |
| |
| jh.join().unwrap(); |
| }); |
| } |