aboutsummaryrefslogtreecommitdiff
path: root/tests/wait_group.rs
blob: 0ec4a729ca76b6b7adf5f897b520dbc0913a1943 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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]
#[cfg_attr(miri, ignore)] // this test makes timing assumptions, but Miri is so slow it violates them
fn wait_and_drop() {
    let wg = WaitGroup::new();
    let (tx, rx) = mpsc::channel();

    for _ in 0..THREADS {
        let wg = wg.clone();
        let tx = tx.clone();

        thread::spawn(move || {
            thread::sleep(Duration::from_millis(100));
            tx.send(()).unwrap();
            drop(wg);
        });
    }

    // At this point, all spawned threads should be in `thread::sleep`, 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.try_recv().unwrap();
    }
}