Skip to content

Commit ff7835f

Browse files
committed
reorder mutex tests
This commit simply helps discern the actual changes needed to test both poison and nonpoison locks.
1 parent 29658d7 commit ff7835f

File tree

1 file changed

+158
-144
lines changed

1 file changed

+158
-144
lines changed

library/std/tests/sync/mutex.rs

Lines changed: 158 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,9 @@ use std::sync::mpsc::channel;
66
use std::sync::{Arc, Condvar, MappedMutexGuard, Mutex, MutexGuard, TryLockError};
77
use std::{hint, mem, thread};
88

9-
struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
10-
11-
#[derive(Eq, PartialEq, Debug)]
12-
struct NonCopy(i32);
13-
14-
#[derive(Eq, PartialEq, Debug)]
15-
struct NonCopyNeedsDrop(i32);
16-
17-
impl Drop for NonCopyNeedsDrop {
18-
fn drop(&mut self) {
19-
hint::black_box(());
20-
}
21-
}
22-
23-
#[test]
24-
fn test_needs_drop() {
25-
assert!(!mem::needs_drop::<NonCopy>());
26-
assert!(mem::needs_drop::<NonCopyNeedsDrop>());
27-
}
28-
29-
#[derive(Clone, Eq, PartialEq, Debug)]
30-
struct Cloneable(i32);
9+
////////////////////////////////////////////////////////////////////////////////////////////////////
10+
// Nonpoison & Poison Tests
11+
////////////////////////////////////////////////////////////////////////////////////////////////////
3112

3213
#[test]
3314
fn smoke() {
@@ -78,19 +59,22 @@ fn try_lock() {
7859
*m.try_lock().unwrap() = ();
7960
}
8061

81-
fn new_poisoned_mutex<T>(value: T) -> Mutex<T> {
82-
let mutex = Mutex::new(value);
83-
84-
let catch_unwind_result = panic::catch_unwind(AssertUnwindSafe(|| {
85-
let _guard = mutex.lock().unwrap();
62+
#[derive(Eq, PartialEq, Debug)]
63+
struct NonCopy(i32);
8664

87-
panic!("test panic to poison mutex");
88-
}));
65+
#[derive(Eq, PartialEq, Debug)]
66+
struct NonCopyNeedsDrop(i32);
8967

90-
assert!(catch_unwind_result.is_err());
91-
assert!(mutex.is_poisoned());
68+
impl Drop for NonCopyNeedsDrop {
69+
fn drop(&mut self) {
70+
hint::black_box(());
71+
}
72+
}
9273

93-
mutex
74+
#[test]
75+
fn test_needs_drop() {
76+
assert!(!mem::needs_drop::<NonCopy>());
77+
assert!(mem::needs_drop::<NonCopyNeedsDrop>());
9478
}
9579

9680
#[test]
@@ -117,6 +101,143 @@ fn test_into_inner_drop() {
117101
assert_eq!(num_drops.load(Ordering::SeqCst), 1);
118102
}
119103

104+
#[test]
105+
fn test_get_mut() {
106+
let mut m = Mutex::new(NonCopy(10));
107+
*m.get_mut().unwrap() = NonCopy(20);
108+
assert_eq!(m.into_inner().unwrap(), NonCopy(20));
109+
}
110+
111+
#[test]
112+
fn test_get_cloned() {
113+
#[derive(Clone, Eq, PartialEq, Debug)]
114+
struct Cloneable(i32);
115+
116+
let m = Mutex::new(Cloneable(10));
117+
118+
assert_eq!(m.get_cloned().unwrap(), Cloneable(10));
119+
}
120+
121+
#[test]
122+
fn test_set() {
123+
fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T)
124+
where
125+
T: Debug + Eq,
126+
{
127+
let m = Mutex::new(init());
128+
129+
assert_eq!(*m.lock().unwrap(), init());
130+
m.set(value()).unwrap();
131+
assert_eq!(*m.lock().unwrap(), value());
132+
}
133+
134+
inner(|| NonCopy(10), || NonCopy(20));
135+
inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20));
136+
}
137+
138+
#[test]
139+
fn test_replace() {
140+
fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T)
141+
where
142+
T: Debug + Eq,
143+
{
144+
let m = Mutex::new(init());
145+
146+
assert_eq!(*m.lock().unwrap(), init());
147+
assert_eq!(m.replace(value()).unwrap(), init());
148+
assert_eq!(*m.lock().unwrap(), value());
149+
}
150+
151+
inner(|| NonCopy(10), || NonCopy(20));
152+
inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20));
153+
}
154+
155+
#[test]
156+
fn test_mutex_arc_condvar() {
157+
struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
158+
159+
let packet = Packet(Arc::new((Mutex::new(false), Condvar::new())));
160+
let packet2 = Packet(packet.0.clone());
161+
let (tx, rx) = channel();
162+
let _t = thread::spawn(move || {
163+
// wait until parent gets in
164+
rx.recv().unwrap();
165+
let &(ref lock, ref cvar) = &*packet2.0;
166+
let mut lock = lock.lock().unwrap();
167+
*lock = true;
168+
cvar.notify_one();
169+
});
170+
171+
let &(ref lock, ref cvar) = &*packet.0;
172+
let mut lock = lock.lock().unwrap();
173+
tx.send(()).unwrap();
174+
assert!(!*lock);
175+
while !*lock {
176+
lock = cvar.wait(lock).unwrap();
177+
}
178+
}
179+
180+
#[test]
181+
fn test_mutex_arc_nested() {
182+
// Tests nested mutexes and access
183+
// to underlying data.
184+
let arc = Arc::new(Mutex::new(1));
185+
let arc2 = Arc::new(Mutex::new(arc));
186+
let (tx, rx) = channel();
187+
let _t = thread::spawn(move || {
188+
let lock = arc2.lock().unwrap();
189+
let lock2 = lock.lock().unwrap();
190+
assert_eq!(*lock2, 1);
191+
tx.send(()).unwrap();
192+
});
193+
rx.recv().unwrap();
194+
}
195+
196+
#[test]
197+
fn test_mutex_unsized() {
198+
let mutex: &Mutex<[i32]> = &Mutex::new([1, 2, 3]);
199+
{
200+
let b = &mut *mutex.lock().unwrap();
201+
b[0] = 4;
202+
b[2] = 5;
203+
}
204+
let comp: &[i32] = &[4, 2, 5];
205+
assert_eq!(&*mutex.lock().unwrap(), comp);
206+
}
207+
208+
#[test]
209+
fn test_mapping_mapped_guard() {
210+
let arr = [0; 4];
211+
let mut lock = Mutex::new(arr);
212+
let guard = lock.lock().unwrap();
213+
let guard = MutexGuard::map(guard, |arr| &mut arr[..2]);
214+
let mut guard = MappedMutexGuard::map(guard, |slice| &mut slice[1..]);
215+
assert_eq!(guard.len(), 1);
216+
guard[0] = 42;
217+
drop(guard);
218+
assert_eq!(*lock.get_mut().unwrap(), [0, 42, 0, 0]);
219+
}
220+
221+
////////////////////////////////////////////////////////////////////////////////////////////////////
222+
// Poison Tests
223+
////////////////////////////////////////////////////////////////////////////////////////////////////
224+
225+
/// Creates a mutex that is immediately poisoned.
226+
fn new_poisoned_mutex<T>(value: T) -> Mutex<T> {
227+
let mutex = Mutex::new(value);
228+
229+
let catch_unwind_result = panic::catch_unwind(AssertUnwindSafe(|| {
230+
let _guard = mutex.lock().unwrap();
231+
232+
panic!("test panic to poison mutex");
233+
}));
234+
235+
assert!(catch_unwind_result.is_err());
236+
assert!(mutex.is_poisoned());
237+
238+
mutex
239+
}
240+
120241
#[test]
121242
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
122243
fn test_into_inner_poison() {
@@ -128,16 +249,12 @@ fn test_into_inner_poison() {
128249
}
129250
}
130251

131-
#[test]
132-
fn test_get_cloned() {
133-
let m = Mutex::new(Cloneable(10));
134-
135-
assert_eq!(m.get_cloned().unwrap(), Cloneable(10));
136-
}
137-
138252
#[test]
139253
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
140254
fn test_get_cloned_poison() {
255+
#[derive(Clone, Eq, PartialEq, Debug)]
256+
struct Cloneable(i32);
257+
141258
let m = new_poisoned_mutex(Cloneable(10));
142259

143260
match m.get_cloned() {
@@ -146,13 +263,6 @@ fn test_get_cloned_poison() {
146263
}
147264
}
148265

149-
#[test]
150-
fn test_get_mut() {
151-
let mut m = Mutex::new(NonCopy(10));
152-
*m.get_mut().unwrap() = NonCopy(20);
153-
assert_eq!(m.into_inner().unwrap(), NonCopy(20));
154-
}
155-
156266
#[test]
157267
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
158268
fn test_get_mut_poison() {
@@ -164,23 +274,6 @@ fn test_get_mut_poison() {
164274
}
165275
}
166276

167-
#[test]
168-
fn test_set() {
169-
fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T)
170-
where
171-
T: Debug + Eq,
172-
{
173-
let m = Mutex::new(init());
174-
175-
assert_eq!(*m.lock().unwrap(), init());
176-
m.set(value()).unwrap();
177-
assert_eq!(*m.lock().unwrap(), value());
178-
}
179-
180-
inner(|| NonCopy(10), || NonCopy(20));
181-
inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20));
182-
}
183-
184277
#[test]
185278
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
186279
fn test_set_poison() {
@@ -203,23 +296,6 @@ fn test_set_poison() {
203296
inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20));
204297
}
205298

206-
#[test]
207-
fn test_replace() {
208-
fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T)
209-
where
210-
T: Debug + Eq,
211-
{
212-
let m = Mutex::new(init());
213-
214-
assert_eq!(*m.lock().unwrap(), init());
215-
assert_eq!(m.replace(value()).unwrap(), init());
216-
assert_eq!(*m.lock().unwrap(), value());
217-
}
218-
219-
inner(|| NonCopy(10), || NonCopy(20));
220-
inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20));
221-
}
222-
223299
#[test]
224300
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
225301
fn test_replace_poison() {
@@ -242,32 +318,11 @@ fn test_replace_poison() {
242318
inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20));
243319
}
244320

245-
#[test]
246-
fn test_mutex_arc_condvar() {
247-
let packet = Packet(Arc::new((Mutex::new(false), Condvar::new())));
248-
let packet2 = Packet(packet.0.clone());
249-
let (tx, rx) = channel();
250-
let _t = thread::spawn(move || {
251-
// wait until parent gets in
252-
rx.recv().unwrap();
253-
let &(ref lock, ref cvar) = &*packet2.0;
254-
let mut lock = lock.lock().unwrap();
255-
*lock = true;
256-
cvar.notify_one();
257-
});
258-
259-
let &(ref lock, ref cvar) = &*packet.0;
260-
let mut lock = lock.lock().unwrap();
261-
tx.send(()).unwrap();
262-
assert!(!*lock);
263-
while !*lock {
264-
lock = cvar.wait(lock).unwrap();
265-
}
266-
}
267-
268321
#[test]
269322
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
270323
fn test_arc_condvar_poison() {
324+
struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
325+
271326
let packet = Packet(Arc::new((Mutex::new(1), Condvar::new())));
272327
let packet2 = Packet(packet.0.clone());
273328
let (tx, rx) = channel();
@@ -326,22 +381,6 @@ fn test_mutex_arc_poison_mapped() {
326381
assert!(arc.is_poisoned());
327382
}
328383

329-
#[test]
330-
fn test_mutex_arc_nested() {
331-
// Tests nested mutexes and access
332-
// to underlying data.
333-
let arc = Arc::new(Mutex::new(1));
334-
let arc2 = Arc::new(Mutex::new(arc));
335-
let (tx, rx) = channel();
336-
let _t = thread::spawn(move || {
337-
let lock = arc2.lock().unwrap();
338-
let lock2 = lock.lock().unwrap();
339-
assert_eq!(*lock2, 1);
340-
tx.send(()).unwrap();
341-
});
342-
rx.recv().unwrap();
343-
}
344-
345384
#[test]
346385
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
347386
fn test_mutex_arc_access_in_unwind() {
@@ -364,31 +403,6 @@ fn test_mutex_arc_access_in_unwind() {
364403
assert_eq!(*lock, 2);
365404
}
366405

367-
#[test]
368-
fn test_mutex_unsized() {
369-
let mutex: &Mutex<[i32]> = &Mutex::new([1, 2, 3]);
370-
{
371-
let b = &mut *mutex.lock().unwrap();
372-
b[0] = 4;
373-
b[2] = 5;
374-
}
375-
let comp: &[i32] = &[4, 2, 5];
376-
assert_eq!(&*mutex.lock().unwrap(), comp);
377-
}
378-
379-
#[test]
380-
fn test_mapping_mapped_guard() {
381-
let arr = [0; 4];
382-
let mut lock = Mutex::new(arr);
383-
let guard = lock.lock().unwrap();
384-
let guard = MutexGuard::map(guard, |arr| &mut arr[..2]);
385-
let mut guard = MappedMutexGuard::map(guard, |slice| &mut slice[1..]);
386-
assert_eq!(guard.len(), 1);
387-
guard[0] = 42;
388-
drop(guard);
389-
assert_eq!(*lock.get_mut().unwrap(), [0, 42, 0, 0]);
390-
}
391-
392406
#[test]
393407
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
394408
fn panic_while_mapping_unlocked_poison() {

0 commit comments

Comments
 (0)