]> git.proxmox.com Git - rustc.git/blob - vendor/crossbeam-channel/tests/thread_locals.rs
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / vendor / crossbeam-channel / tests / thread_locals.rs
1 //! Tests that make sure accessing thread-locals while exiting the thread doesn't cause panics.
2
3 #[macro_use]
4 extern crate crossbeam_channel;
5 extern crate crossbeam_utils;
6
7 use std::thread;
8 use std::time::Duration;
9
10 use crossbeam_channel::unbounded;
11 use crossbeam_utils::thread::scope;
12
13 fn ms(ms: u64) -> Duration {
14 Duration::from_millis(ms)
15 }
16
17 #[test]
18 #[cfg_attr(target_os = "macos", ignore = "TLS is destroyed too early on macOS")]
19 fn use_while_exiting() {
20 struct Foo;
21
22 impl Drop for Foo {
23 fn drop(&mut self) {
24 // A blocking operation after the thread-locals have been dropped. This will attempt to
25 // use the thread-locals and must not panic.
26 let (_s, r) = unbounded::<()>();
27 select! {
28 recv(r) -> _ => {}
29 default(ms(100)) => {}
30 }
31 }
32 }
33
34 thread_local! {
35 static FOO: Foo = Foo;
36 }
37
38 let (s, r) = unbounded::<()>();
39
40 scope(|scope| {
41 scope.spawn(|_| {
42 // First initialize `FOO`, then the thread-locals related to crossbeam-channel.
43 FOO.with(|_| ());
44 r.recv().unwrap();
45 // At thread exit, thread-locals related to crossbeam-channel get dropped first and
46 // `FOO` is dropped last.
47 });
48
49 scope.spawn(|_| {
50 thread::sleep(ms(100));
51 s.send(()).unwrap();
52 });
53 })
54 .unwrap();
55 }