]>
git.proxmox.com Git - cargo.git/blob - vendor/crossbeam-utils/tests/sharded_lock.rs
1 use std
::sync
::atomic
::{AtomicUsize, Ordering}
;
2 use std
::sync
::mpsc
::channel
;
3 use std
::sync
::{Arc, TryLockError}
;
6 use crossbeam_utils
::sync
::ShardedLock
;
9 #[derive(Eq, PartialEq, Debug)]
14 let l
= ShardedLock
::new(());
15 drop(l
.read().unwrap());
16 drop(l
.write().unwrap());
17 drop((l
.read().unwrap(), l
.read().unwrap()));
18 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();
60 assert
!(arc
.read().is_err());
65 let arc
= Arc
::new(ShardedLock
::new(1));
66 assert
!(!arc
.is_poisoned());
67 let arc2
= arc
.clone();
68 let _
: Result
<(), _
> = thread
::spawn(move || {
69 let _lock
= arc2
.write().unwrap();
73 assert
!(arc
.write().is_err());
74 assert
!(arc
.is_poisoned());
78 fn arc_no_poison_rr() {
79 let arc
= Arc
::new(ShardedLock
::new(1));
80 let arc2
= arc
.clone();
81 let _
: Result
<(), _
> = thread
::spawn(move || {
82 let _lock
= arc2
.read().unwrap();
86 let lock
= arc
.read().unwrap();
90 fn arc_no_poison_sl() {
91 let arc
= Arc
::new(ShardedLock
::new(1));
92 let arc2
= arc
.clone();
93 let _
: Result
<(), _
> = thread
::spawn(move || {
94 let _lock
= arc2
.read().unwrap();
98 let lock
= arc
.write().unwrap();
104 let arc
= Arc
::new(ShardedLock
::new(0));
105 let arc2
= arc
.clone();
106 let (tx
, rx
) = channel();
108 thread
::spawn(move || {
109 let mut lock
= arc2
.write().unwrap();
116 tx
.send(()).unwrap();
119 // Readers try to catch the writer in the act
120 let mut children
= Vec
::new();
122 let arc3
= arc
.clone();
123 children
.push(thread
::spawn(move || {
124 let lock
= arc3
.read().unwrap();
129 // Wait for children to pass their asserts
131 assert
!(r
.join().is_ok());
134 // Wait for writer to finish
136 let lock
= arc
.read().unwrap();
137 assert_eq
!(*lock
, 10);
141 fn arc_access_in_unwind() {
142 let arc
= Arc
::new(ShardedLock
::new(1));
143 let arc2
= arc
.clone();
144 let _
= thread
::spawn(move || {
146 i
: Arc
<ShardedLock
<isize>>,
148 impl Drop
for Unwinder
{
150 let mut lock
= self.i
.write().unwrap();
154 let _u
= Unwinder { i: arc2 }
;
158 let lock
= arc
.read().unwrap();
159 assert_eq
!(*lock
, 2);
164 let sl
: &ShardedLock
<[i32]> = &ShardedLock
::new([1, 2, 3]);
166 let b
= &mut *sl
.write().unwrap();
170 let comp
: &[i32] = &[4, 2, 5];
171 assert_eq
!(&*sl
.read().unwrap(), comp
);
176 let lock
= ShardedLock
::new(0isize
);
177 let read_guard
= lock
.read().unwrap();
179 let write_result
= lock
.try_write();
181 Err(TryLockError
::WouldBlock
) => (),
182 Ok(_
) => panic
!("try_write should not succeed while read_guard is in scope"),
183 Err(_
) => panic
!("unexpected error"),
190 fn test_into_inner() {
191 let m
= ShardedLock
::new(NonCopy(10));
192 assert_eq
!(m
.into_inner().unwrap(), NonCopy(10));
196 fn test_into_inner_drop() {
197 struct Foo(Arc
<AtomicUsize
>);
200 self.0.fetch_add
(1, Ordering
::SeqCst
);
203 let num_drops
= Arc
::new(AtomicUsize
::new(0));
204 let m
= ShardedLock
::new(Foo(num_drops
.clone()));
205 assert_eq
!(num_drops
.load(Ordering
::SeqCst
), 0);
207 let _inner
= m
.into_inner().unwrap();
208 assert_eq
!(num_drops
.load(Ordering
::SeqCst
), 0);
210 assert_eq
!(num_drops
.load(Ordering
::SeqCst
), 1);
214 fn test_into_inner_poison() {
215 let m
= Arc
::new(ShardedLock
::new(NonCopy(10)));
217 let _
= thread
::spawn(move || {
218 let _lock
= m2
.write().unwrap();
219 panic
!("test panic in inner thread to poison ShardedLock");
223 assert
!(m
.is_poisoned());
224 match Arc
::try_unwrap(m
).unwrap().into_inner() {
225 Err(e
) => assert_eq
!(e
.into_inner(), NonCopy(10)),
226 Ok(x
) => panic
!("into_inner of poisoned ShardedLock is Ok: {:?}", x
),
232 let mut m
= ShardedLock
::new(NonCopy(10));
233 *m
.get_mut().unwrap() = NonCopy(20);
234 assert_eq
!(m
.into_inner().unwrap(), NonCopy(20));
238 fn test_get_mut_poison() {
239 let m
= Arc
::new(ShardedLock
::new(NonCopy(10)));
241 let _
= thread
::spawn(move || {
242 let _lock
= m2
.write().unwrap();
243 panic
!("test panic in inner thread to poison ShardedLock");
247 assert
!(m
.is_poisoned());
248 match Arc
::try_unwrap(m
).unwrap().get_mut() {
249 Err(e
) => assert_eq
!(*e
.into_inner(), NonCopy(10)),
250 Ok(x
) => panic
!("get_mut of poisoned ShardedLock is Ok: {:?}", x
),