]> git.proxmox.com Git - rustc.git/blob - vendor/crossbeam-utils-0.6.6/tests/thread.rs
New upstream version 1.51.0+dfsg1
[rustc.git] / vendor / crossbeam-utils-0.6.6 / tests / thread.rs
1 extern crate crossbeam_utils;
2
3 use std::any::Any;
4 use std::sync::atomic::{AtomicUsize, Ordering};
5 use std::thread::sleep;
6 use std::time::Duration;
7
8 use crossbeam_utils::thread;
9
10 const THREADS: usize = 10;
11 const SMALL_STACK_SIZE: usize = 20;
12
13 #[test]
14 fn join() {
15 let counter = AtomicUsize::new(0);
16 thread::scope(|scope| {
17 let handle = scope.spawn(|_| {
18 counter.store(1, Ordering::Relaxed);
19 });
20 assert!(handle.join().is_ok());
21
22 let panic_handle = scope.spawn(|_| {
23 panic!("\"My honey is running out!\", said Pooh.");
24 });
25 assert!(panic_handle.join().is_err());
26 })
27 .unwrap();
28
29 // There should be sufficient synchronization.
30 assert_eq!(1, counter.load(Ordering::Relaxed));
31 }
32
33 #[test]
34 fn counter() {
35 let counter = AtomicUsize::new(0);
36 thread::scope(|scope| {
37 for _ in 0..THREADS {
38 scope.spawn(|_| {
39 counter.fetch_add(1, Ordering::Relaxed);
40 });
41 }
42 })
43 .unwrap();
44
45 assert_eq!(THREADS, counter.load(Ordering::Relaxed));
46 }
47
48 #[test]
49 fn counter_builder() {
50 let counter = AtomicUsize::new(0);
51 thread::scope(|scope| {
52 for i in 0..THREADS {
53 scope
54 .builder()
55 .name(format!("child-{}", i))
56 .stack_size(SMALL_STACK_SIZE)
57 .spawn(|_| {
58 counter.fetch_add(1, Ordering::Relaxed);
59 })
60 .unwrap();
61 }
62 })
63 .unwrap();
64
65 assert_eq!(THREADS, counter.load(Ordering::Relaxed));
66 }
67
68 #[test]
69 fn counter_panic() {
70 let counter = AtomicUsize::new(0);
71 let result = thread::scope(|scope| {
72 scope.spawn(|_| {
73 panic!("\"My honey is running out!\", said Pooh.");
74 });
75 sleep(Duration::from_millis(100));
76
77 for _ in 0..THREADS {
78 scope.spawn(|_| {
79 counter.fetch_add(1, Ordering::Relaxed);
80 });
81 }
82 });
83
84 assert_eq!(THREADS, counter.load(Ordering::Relaxed));
85 assert!(result.is_err());
86 }
87
88 #[test]
89 fn panic_twice() {
90 let result = thread::scope(|scope| {
91 scope.spawn(|_| {
92 sleep(Duration::from_millis(500));
93 panic!("thread #1");
94 });
95 scope.spawn(|_| {
96 panic!("thread #2");
97 });
98 });
99
100 let err = result.unwrap_err();
101 let vec = err
102 .downcast_ref::<Vec<Box<Any + Send + 'static>>>()
103 .unwrap();
104 assert_eq!(2, vec.len());
105
106 let first = vec[0].downcast_ref::<&str>().unwrap();
107 let second = vec[1].downcast_ref::<&str>().unwrap();
108 assert_eq!("thread #1", *first);
109 assert_eq!("thread #2", *second)
110 }
111
112 #[test]
113 fn panic_many() {
114 let result = thread::scope(|scope| {
115 scope.spawn(|_| panic!("deliberate panic #1"));
116 scope.spawn(|_| panic!("deliberate panic #2"));
117 scope.spawn(|_| panic!("deliberate panic #3"));
118 });
119
120 let err = result.unwrap_err();
121 let vec = err
122 .downcast_ref::<Vec<Box<Any + Send + 'static>>>()
123 .unwrap();
124 assert_eq!(3, vec.len());
125
126 for panic in vec.iter() {
127 let panic = panic.downcast_ref::<&str>().unwrap();
128 assert!(
129 *panic == "deliberate panic #1"
130 || *panic == "deliberate panic #2"
131 || *panic == "deliberate panic #3"
132 );
133 }
134 }
135
136 #[test]
137 fn nesting() {
138 let var = "foo".to_string();
139
140 struct Wrapper<'a> {
141 var: &'a String,
142 }
143
144 impl<'a> Wrapper<'a> {
145 fn recurse(&'a self, scope: &thread::Scope<'a>, depth: usize) {
146 assert_eq!(self.var, "foo");
147
148 if depth > 0 {
149 scope.spawn(move |scope| {
150 self.recurse(scope, depth - 1);
151 });
152 }
153 }
154 }
155
156 let wrapper = Wrapper { var: &var };
157
158 thread::scope(|scope| {
159 scope.spawn(|scope| {
160 scope.spawn(|scope| {
161 wrapper.recurse(scope, 5);
162 });
163 });
164 })
165 .unwrap();
166 }
167
168 #[test]
169 fn join_nested() {
170 thread::scope(|scope| {
171 scope.spawn(|scope| {
172 let handle = scope.spawn(|_| 7);
173
174 sleep(Duration::from_millis(200));
175 handle.join().unwrap();
176 });
177
178 sleep(Duration::from_millis(100));
179 })
180 .unwrap();
181 }