1use super::*;
4use std::sync::*;
5use std::sync::atomic::*;
6use std::sync::mpsc::*;
7use std::thread;
8use std::time::Duration;
9
10wrap_from!(Arc);
15
16#[cfg(not(MIN_VER_1_24_0))]
17wrap_ctor!(Mutex);
18#[cfg(MIN_VER_1_24_0)]
19wrap_from!(Mutex);
20
21#[cfg(not(MIN_VER_1_24_0))]
22wrap_ctor!(RwLock);
23#[cfg(MIN_VER_1_24_0)]
24wrap_from!(RwLock);
25
26arbitrary!(Barrier, SMapped<'a, u16, Self>; static_map(any::<u16>(), |n| Barrier::new(n as usize))
28);
29
30arbitrary!(BarrierWaitResult,
31 TupleUnion<(W<FnGenerator<Self>>, W<FnGenerator<Self>>)>;
32 prop_oneof![FnGenerator::new(bwr_true), FnGenerator::new(bwr_false)]
33);
34
35generator!(
36 Condvar, default;
37 Once, Once::new
38);
39
40arbitrary!(WaitTimeoutResult, TupleUnion<(W<Just<Self>>, W<Just<Self>>)>;
41 prop_oneof![Just(wtr_true()), Just(wtr_false())]
42);
43
44fn bwr_true() -> BarrierWaitResult {
45 Barrier::new(1).wait()
46}
47
48fn bwr_false() -> BarrierWaitResult {
49 let barrier = Arc::new(Barrier::new(2));
50 let b2 = barrier.clone();
51 let jh = thread::spawn(move|| { b2.wait() });
52 let bwr1 = barrier.wait();
53 let bwr2 = jh.join().unwrap();
54 if bwr1.is_leader() { bwr2 } else { bwr1 }
55}
56
57fn wtr_false() -> WaitTimeoutResult {
58 let cvar = Arc::new(Condvar::new());
59 let cvar2 = cvar.clone();
60 thread::spawn(move|| { cvar2.notify_one(); });
61 let lock = Mutex::new(());
62 let wt = cvar.wait_timeout(lock.lock().unwrap(), Duration::from_millis(1));
63 let (_, wtr) = wt.unwrap();
64 wtr
65}
66
67fn wtr_true() -> WaitTimeoutResult {
68 let cvar = Condvar::new();
69 let lock = Mutex::new(());
70 let wt = cvar.wait_timeout(lock.lock().unwrap(), Duration::from_millis(0));
71 let (_, wtr) = wt.unwrap();
72 wtr
73}
74
75macro_rules! atomic {
76 ($($type: ident, $base: ty);+) => {
77 $(arbitrary!($type, SMapped<'a, $base, Self>;
78 any_with_smap((), $type::new)
79 );)+
80 };
81}
82
83atomic!(AtomicBool, bool; AtomicIsize, isize; AtomicUsize, usize);
85
86#[cfg(feature = "unstable")]
87atomic!(AtomicI8, i8; AtomicI16, i16; AtomicI32, i32; AtomicI64, i64;
88 AtomicU8, u8; AtomicU16, u16; AtomicU32, u32; AtomicU64, u64);
89
90arbitrary!(Ordering,
91 TupleUnion<(W<Just<Self>>, W<Just<Self>>, W<Just<Self>>,
92 W<Just<Self>>, W<Just<Self>>)>;
93 prop_oneof![
94 Just(Ordering::Relaxed),
95 Just(Ordering::Release),
96 Just(Ordering::Acquire),
97 Just(Ordering::AcqRel),
98 Just(Ordering::SeqCst)
99 ]
100);
101
102arbitrary!(RecvError; RecvError);
103
104arbitrary!([T: Arbitrary<'a>] SendError<T>, SMapped<'a, T, Self>, T::Parameters;
105 args => any_with_smap(args, SendError)
106);
107
108arbitrary!(RecvTimeoutError, TupleUnion<(W<Just<Self>>, W<Just<Self>>)>;
109 prop_oneof![
110 Just(RecvTimeoutError::Disconnected),
111 Just(RecvTimeoutError::Timeout)
112 ]
113);
114
115arbitrary!(TryRecvError, TupleUnion<(W<Just<Self>>, W<Just<Self>>)>;
116 prop_oneof![
117 Just(TryRecvError::Disconnected),
118 Just(TryRecvError::Empty)
119 ]
120);
121
122arbitrary!(
123 [P: Clone + Default, T: Arbitrary<'a, Parameters = P>] TrySendError<T>,
124 TupleUnion<(W<SMapped<'a, T, Self>>, W<SMapped<'a, T, Self>>)>, P;
125 args => prop_oneof![
126 any_with_smap(args.clone(), TrySendError::Disconnected),
127 any_with_smap(args, TrySendError::Full),
128 ]
129);
130
131#[cfg(feature = "unstable")]
132generator!(Select, Select::new);
133
134arbitrary!([A] (Sender<A>, Receiver<A>), FnGenerator<Self>;
137 FnGenerator::new(channel)
138);
139
140arbitrary!([A: Debug] (Sender<A>, IntoIter<A>), FnGenerator<Self>;
141 FnGenerator::new(|| {
142 let (rx, tx) = channel();
143 (rx, tx.into_iter())
144 })
145);
146
147arbitrary!([A] (SyncSender<A>, Receiver<A>), SMapped<'a, u16, Self>;
148 static_map(any::<u16>(), |size| sync_channel(size as usize))
149);
150
151arbitrary!([A: Debug] (SyncSender<A>, IntoIter<A>), SMapped<'a, u16, Self>;
152 static_map(any::<u16>(), |size| {
153 let (rx, tx) = sync_channel(size as usize);
154 (rx, tx.into_iter())
155 })
156);
157
158#[cfg(test)]
159mod test {
160 no_panic_test!(
161 arc => Arc<u8>,
162 mutex => Mutex<u8>,
163 rw_lock => RwLock<u8>,
164 barrier => Barrier,
165 barrier_wait_result => BarrierWaitResult,
166 condvar => Condvar,
167 once => Once,
168 wait_timeout_result => WaitTimeoutResult,
169 atomic_bool => AtomicBool,
170 atomic_isize => AtomicIsize,
171 atomic_usize => AtomicUsize,
172 ordering => Ordering,
173 recv_error => RecvError,
174 send_error => SendError<u8>,
175 recv_timeout_error => RecvTimeoutError,
176 try_recv_error => TryRecvError,
177 try_send_error => TrySendError<u8>,
178 rx_tx => (Sender<u8>, Receiver<u8>),
179 rx_txiter => (Sender<u8>, IntoIter<u8>),
180 syncrx_tx => (SyncSender<u8>, Receiver<u8>),
181 syncrx_txiter => (SyncSender<u8>, IntoIter<u8>)
182 );
183
184 #[cfg(feature = "unstable")]
185 no_panic_test!(
186 select => Select,
187 atomic_i8 => AtomicI8,
188 atomic_i16 => AtomicI16,
189 atomic_i32 => AtomicI32,
190 atomic_i64 => AtomicI64,
191 atomic_u8 => AtomicU8,
192 atomic_u16 => AtomicU16,
193 atomic_u32 => AtomicU32,
194 atomic_u64 => AtomicU64
195 );
196}