]>
git.proxmox.com Git - rustc.git/blob - vendor/crossbeam-utils/tests/sharded_lock.rs
1 extern crate crossbeam_utils
;
4 use std
::sync
::mpsc
::channel
;
6 use std
::sync
::{Arc, TryLockError}
;
7 use std
::sync
::atomic
::{AtomicUsize, Ordering}
;
9 use crossbeam_utils
::sync
::ShardedLock
;
12 #[derive(Eq, PartialEq, Debug)]
17 let l
= ShardedLock
::new(());
18 drop(l
.read().unwrap());
19 drop(l
.write().unwrap());
20 drop((l
.read().unwrap(), l
.read().unwrap()));
21 drop(l
.write().unwrap());
27 const M
: usize = 1000;
29 let r
= Arc
::new(ShardedLock
::new(()));
31 let (tx
, rx
) = channel
::<()>();
35 thread
::spawn(move || {
36 let mut rng
= rand
::thread_rng();
38 if rng
.gen_bool(1.0 / (N
as f64)) {
39 drop(r
.write().unwrap());
41 drop(r
.read().unwrap());
53 let arc
= Arc
::new(ShardedLock
::new(1));
54 let arc2
= arc
.clone();
55 let _
: Result
<(), _
> = thread
::spawn(move || {
56 let _lock
= arc2
.write().unwrap();
59 assert
!(arc
.read().is_err());
64 let arc
= Arc
::new(ShardedLock
::new(1));
65 assert
!(!arc
.is_poisoned());
66 let arc2
= arc
.clone();
67 let _
: Result
<(), _
> = thread
::spawn(move || {
68 let _lock
= arc2
.write().unwrap();
71 assert
!(arc
.write().is_err());
72 assert
!(arc
.is_poisoned());
76 fn arc_no_poison_rr() {
77 let arc
= Arc
::new(ShardedLock
::new(1));
78 let arc2
= arc
.clone();
79 let _
: Result
<(), _
> = thread
::spawn(move || {
80 let _lock
= arc2
.read().unwrap();
83 let lock
= arc
.read().unwrap();
87 fn arc_no_poison_sl() {
88 let arc
= Arc
::new(ShardedLock
::new(1));
89 let arc2
= arc
.clone();
90 let _
: Result
<(), _
> = thread
::spawn(move || {
91 let _lock
= arc2
.read().unwrap();
94 let lock
= arc
.write().unwrap();
100 let arc
= Arc
::new(ShardedLock
::new(0));
101 let arc2
= arc
.clone();
102 let (tx
, rx
) = channel();
104 thread
::spawn(move || {
105 let mut lock
= arc2
.write().unwrap();
112 tx
.send(()).unwrap();
115 // Readers try to catch the writer in the act
116 let mut children
= Vec
::new();
118 let arc3
= arc
.clone();
119 children
.push(thread
::spawn(move || {
120 let lock
= arc3
.read().unwrap();
125 // Wait for children to pass their asserts
127 assert
!(r
.join().is_ok());
130 // Wait for writer to finish
132 let lock
= arc
.read().unwrap();
133 assert_eq
!(*lock
, 10);
137 fn arc_access_in_unwind() {
138 let arc
= Arc
::new(ShardedLock
::new(1));
139 let arc2
= arc
.clone();
140 let _
= thread
::spawn(move || -> () {
142 i
: Arc
<ShardedLock
<isize>>,
144 impl Drop
for Unwinder
{
146 let mut lock
= self.i
.write().unwrap();
150 let _u
= Unwinder { i: arc2 }
;
153 let lock
= arc
.read().unwrap();
154 assert_eq
!(*lock
, 2);
159 let sl
: &ShardedLock
<[i32]> = &ShardedLock
::new([1, 2, 3]);
161 let b
= &mut *sl
.write().unwrap();
165 let comp
: &[i32] = &[4, 2, 5];
166 assert_eq
!(&*sl
.read().unwrap(), comp
);
171 let lock
= ShardedLock
::new(0isize
);
172 let read_guard
= lock
.read().unwrap();
174 let write_result
= lock
.try_write();
176 Err(TryLockError
::WouldBlock
) => (),
177 Ok(_
) => assert
!(false, "try_write should not succeed while read_guard is in scope"),
178 Err(_
) => assert
!(false, "unexpected error"),
185 fn test_into_inner() {
186 let m
= ShardedLock
::new(NonCopy(10));
187 assert_eq
!(m
.into_inner().unwrap(), NonCopy(10));
191 fn test_into_inner_drop() {
192 struct Foo(Arc
<AtomicUsize
>);
195 self.0.fetch_add
(1, Ordering
::SeqCst
);
198 let num_drops
= Arc
::new(AtomicUsize
::new(0));
199 let m
= ShardedLock
::new(Foo(num_drops
.clone()));
200 assert_eq
!(num_drops
.load(Ordering
::SeqCst
), 0);
202 let _inner
= m
.into_inner().unwrap();
203 assert_eq
!(num_drops
.load(Ordering
::SeqCst
), 0);
205 assert_eq
!(num_drops
.load(Ordering
::SeqCst
), 1);
209 fn test_into_inner_poison() {
210 let m
= Arc
::new(ShardedLock
::new(NonCopy(10)));
212 let _
= thread
::spawn(move || {
213 let _lock
= m2
.write().unwrap();
214 panic
!("test panic in inner thread to poison ShardedLock");
217 assert
!(m
.is_poisoned());
218 match Arc
::try_unwrap(m
).unwrap().into_inner() {
219 Err(e
) => assert_eq
!(e
.into_inner(), NonCopy(10)),
220 Ok(x
) => panic
!("into_inner of poisoned ShardedLock is Ok: {:?}", x
),
226 let mut m
= ShardedLock
::new(NonCopy(10));
227 *m
.get_mut().unwrap() = NonCopy(20);
228 assert_eq
!(m
.into_inner().unwrap(), NonCopy(20));
232 fn test_get_mut_poison() {
233 let m
= Arc
::new(ShardedLock
::new(NonCopy(10)));
235 let _
= thread
::spawn(move || {
236 let _lock
= m2
.write().unwrap();
237 panic
!("test panic in inner thread to poison ShardedLock");
240 assert
!(m
.is_poisoned());
241 match Arc
::try_unwrap(m
).unwrap().get_mut() {
242 Err(e
) => assert_eq
!(*e
.into_inner(), NonCopy(10)),
243 Ok(x
) => panic
!("get_mut of poisoned ShardedLock is Ok: {:?}", x
),