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