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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use crate;
/// Cyclic Barrier implementation.
///
/// It basically provides 2 methods:
///
/// let barrier = CyclicBarrier::new(count); // initialize a cyclic barrier with 3 parties
/// barrier.wait(); // Wait until all parties are wait. Returnes Ok(()) for the last one entered the state
///
/// Most of the time, you should use Arc(barrier).
///
/// You can clone the Arc container of barrier as many times as you want.
/// // You can reuse the barrier if the config does not need to be changed.
///
///
/// drop(barrier); // discard the barrier after you are done with it.
///
/// Usage:
/// Example:
/// ```
/// use std::sync::Arc;
/// use std::time::Duration;
/// use std::thread;
/// use classic_sync::cyclic_barrier::CyclicBarrier;
/// let barrier = CyclicBarrier::new(3);
/// let arc_barrier = Arc::new(barrier);
/// for i in 0..3 {
/// let barrier_copy = Arc::clone(&arc_barrier);
/// let tid = i;
/// thread::spawn(move || {
/// // if you care who's wait call triggered everyone to go, you can check the
/// // firing object returned. If it is Some(_), it triggered the barrier
/// let firing = barrier_copy.wait();
///
/// if firing.is_some() {
/// println!("Thread {tid} is the one triggered it!");
/// }
/// println!("Now we are starting almost at the same time!!");
/// });
/// }
///
///
/// ```
/// Implementation of CyclicBarrier
/// Close internal pthread_barrier_t object on Drop