]>
git.proxmox.com Git - rustc.git/blob - library/std/src/sync/mutex/tests.rs
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);
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
);