1 use crate::sync::atomic::{AtomicUsize, Ordering};
2 use crate::sync::mpsc::channel;
3 use crate::sync::{Arc, Condvar, Mutex};
6 struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
8 #[derive(Eq, PartialEq, Debug)]
13 let m = Mutex::new(());
14 drop(m.lock().unwrap());
15 drop(m.lock().unwrap());
23 let m = Arc::new(Mutex::new(0));
25 fn inc(m: &Mutex<u32>) {
27 *m.lock().unwrap() += 1;
31 let (tx, rx) = channel();
35 thread::spawn(move || {
37 tx2.send(()).unwrap();
41 thread::spawn(move || {
43 tx2.send(()).unwrap();
51 assert_eq!(*m.lock().unwrap(), J * K * 2);
56 let m = Mutex::new(());
57 *m.try_lock().unwrap() = ();
61 fn test_into_inner() {
62 let m = Mutex::new(NonCopy(10));
63 assert_eq!(m.into_inner().unwrap(), NonCopy(10));
67 fn test_into_inner_drop() {
68 struct Foo(Arc<AtomicUsize>);
71 self.0.fetch_add(1, Ordering::SeqCst);
74 let num_drops = Arc::new(AtomicUsize::new(0));
75 let m = Mutex::new(Foo(num_drops.clone()));
76 assert_eq!(num_drops.load(Ordering::SeqCst), 0);
78 let _inner = m.into_inner().unwrap();
79 assert_eq!(num_drops.load(Ordering::SeqCst), 0);
81 assert_eq!(num_drops.load(Ordering::SeqCst), 1);
85 fn test_into_inner_poison() {
86 let m = Arc::new(Mutex::new(NonCopy(10)));
88 let _ = thread::spawn(move || {
89 let _lock = m2.lock().unwrap();
90 panic!("test panic in inner thread to poison mutex");
94 assert!(m.is_poisoned());
95 match Arc::try_unwrap(m).unwrap().into_inner() {
96 Err(e) => assert_eq!(e.into_inner(), NonCopy(10)),
97 Ok(x) => panic!("into_inner of poisoned Mutex is Ok: {x:?}"),
103 let mut m = Mutex::new(NonCopy(10));
104 *m.get_mut().unwrap() = NonCopy(20);
105 assert_eq!(m.into_inner().unwrap(), NonCopy(20));
109 fn test_get_mut_poison() {
110 let m = Arc::new(Mutex::new(NonCopy(10)));
112 let _ = thread::spawn(move || {
113 let _lock = m2.lock().unwrap();
114 panic!("test panic in inner thread to poison mutex");
118 assert!(m.is_poisoned());
119 match Arc::try_unwrap(m).unwrap().get_mut() {
120 Err(e) => assert_eq!(*e.into_inner(), NonCopy(10)),
121 Ok(x) => panic!("get_mut of poisoned Mutex is Ok: {x:?}"),
126 fn test_mutex_arc_condvar() {
127 let packet = Packet(Arc::new((Mutex::new(false), Condvar::new())));
128 let packet2 = Packet(packet.0.clone());
129 let (tx, rx) = channel();
130 let _t = thread::spawn(move || {
131 // wait until parent gets in
133 let &(ref lock, ref cvar) = &*packet2.0;
134 let mut lock = lock.lock().unwrap();
139 let &(ref lock, ref cvar) = &*packet.0;
140 let mut lock = lock.lock().unwrap();
141 tx.send(()).unwrap();
144 lock = cvar.wait(lock).unwrap();
149 fn test_arc_condvar_poison() {
150 let packet = Packet(Arc::new((Mutex::new(1), Condvar::new())));
151 let packet2 = Packet(packet.0.clone());
152 let (tx, rx) = channel();
154 let _t = thread::spawn(move || -> () {
156 let &(ref lock, ref cvar) = &*packet2.0;
157 let _g = lock.lock().unwrap();
159 // Parent should fail when it wakes up.
163 let &(ref lock, ref cvar) = &*packet.0;
164 let mut lock = lock.lock().unwrap();
165 tx.send(()).unwrap();
167 match cvar.wait(lock) {
170 assert_eq!(*lock, 1);
178 fn test_mutex_arc_poison() {
179 let arc = Arc::new(Mutex::new(1));
180 assert!(!arc.is_poisoned());
181 let arc2 = arc.clone();
182 let _ = thread::spawn(move || {
183 let lock = arc2.lock().unwrap();
184 assert_eq!(*lock, 2); // deliberate assertion failure to poison the mutex
187 assert!(arc.lock().is_err());
188 assert!(arc.is_poisoned());
192 fn test_mutex_arc_nested() {
193 // Tests nested mutexes and access
194 // to underlying data.
195 let arc = Arc::new(Mutex::new(1));
196 let arc2 = Arc::new(Mutex::new(arc));
197 let (tx, rx) = channel();
198 let _t = thread::spawn(move || {
199 let lock = arc2.lock().unwrap();
200 let lock2 = lock.lock().unwrap();
201 assert_eq!(*lock2, 1);
202 tx.send(()).unwrap();
208 fn test_mutex_arc_access_in_unwind() {
209 let arc = Arc::new(Mutex::new(1));
210 let arc2 = arc.clone();
211 let _ = thread::spawn(move || -> () {
215 impl Drop for Unwinder {
217 *self.i.lock().unwrap() += 1;
220 let _u = Unwinder { i: arc2 };
224 let lock = arc.lock().unwrap();
225 assert_eq!(*lock, 2);
229 fn test_mutex_unsized() {
230 let mutex: &Mutex<[i32]> = &Mutex::new([1, 2, 3]);
232 let b = &mut *mutex.lock().unwrap();
236 let comp: &[i32] = &[4, 2, 5];
237 assert_eq!(&*mutex.lock().unwrap(), comp);