1 use std::sync::mpsc;
2 use std::thread;
3 use std::time::Duration;
4 
5 use crossbeam_utils::sync::WaitGroup;
6 
7 const THREADS: usize = 10;
8 
9 #[test]
wait()10 fn wait() {
11     let wg = WaitGroup::new();
12     let (tx, rx) = mpsc::channel();
13 
14     for _ in 0..THREADS {
15         let wg = wg.clone();
16         let tx = tx.clone();
17 
18         thread::spawn(move || {
19             wg.wait();
20             tx.send(()).unwrap();
21         });
22     }
23 
24     thread::sleep(Duration::from_millis(100));
25 
26     // At this point, all spawned threads should be blocked, so we shouldn't get anything from the
27     // channel.
28     assert!(rx.try_recv().is_err());
29 
30     wg.wait();
31 
32     // Now, the wait group is cleared and we should receive messages.
33     for _ in 0..THREADS {
34         rx.recv().unwrap();
35     }
36 }
37 
38 #[test]
wait_and_drop()39 fn wait_and_drop() {
40     let wg = WaitGroup::new();
41     let wg2 = WaitGroup::new();
42     let (tx, rx) = mpsc::channel();
43 
44     for _ in 0..THREADS {
45         let wg = wg.clone();
46         let wg2 = wg2.clone();
47         let tx = tx.clone();
48 
49         thread::spawn(move || {
50             wg2.wait();
51             tx.send(()).unwrap();
52             drop(wg);
53         });
54     }
55 
56     // At this point, no thread has gotten past `wg2.wait()`, so we shouldn't get anything from the
57     // channel.
58     assert!(rx.try_recv().is_err());
59     drop(wg2);
60 
61     wg.wait();
62 
63     // Now, the wait group is cleared and we should receive messages.
64     for _ in 0..THREADS {
65         rx.try_recv().unwrap();
66     }
67 }
68