| use std::sync::mpsc; |
| use std::thread; |
| use std::time::Duration; |
| |
| use crossbeam_utils::sync::WaitGroup; |
| |
| const THREADS: usize = 10; |
| |
| #[test] |
| fn wait() { |
| let wg = WaitGroup::new(); |
| let (tx, rx) = mpsc::channel(); |
| |
| for _ in 0..THREADS { |
| let wg = wg.clone(); |
| let tx = tx.clone(); |
| |
| thread::spawn(move || { |
| wg.wait(); |
| tx.send(()).unwrap(); |
| }); |
| } |
| |
| thread::sleep(Duration::from_millis(100)); |
| |
| // At this point, all spawned threads should be blocked, so we shouldn't get anything from the |
| // channel. |
| assert!(rx.try_recv().is_err()); |
| |
| wg.wait(); |
| |
| // Now, the wait group is cleared and we should receive messages. |
| for _ in 0..THREADS { |
| rx.recv().unwrap(); |
| } |
| } |
| |
| #[test] |
| fn wait_and_drop() { |
| let wg = WaitGroup::new(); |
| let wg2 = WaitGroup::new(); |
| let (tx, rx) = mpsc::channel(); |
| |
| for _ in 0..THREADS { |
| let wg = wg.clone(); |
| let wg2 = wg2.clone(); |
| let tx = tx.clone(); |
| |
| thread::spawn(move || { |
| wg2.wait(); |
| tx.send(()).unwrap(); |
| drop(wg); |
| }); |
| } |
| |
| // At this point, no thread has gotten past `wg2.wait()`, so we shouldn't get anything from the |
| // channel. |
| assert!(rx.try_recv().is_err()); |
| drop(wg2); |
| |
| wg.wait(); |
| |
| // Now, the wait group is cleared and we should receive messages. |
| for _ in 0..THREADS { |
| rx.try_recv().unwrap(); |
| } |
| } |