1 use crossbeam_utils::thread;
2 use rayon_core::ThreadPoolBuilder;
3
4 #[derive(PartialEq, Eq, Debug)]
5 struct Local(i32);
6
7 scoped_tls::scoped_thread_local!(static LOCAL: Local);
8
9 #[test]
missing_scoped_tls()10 fn missing_scoped_tls() {
11 LOCAL.set(&Local(42), || {
12 let pool = ThreadPoolBuilder::new()
13 .build()
14 .expect("thread pool created");
15
16 // `LOCAL` is not set in the pool.
17 pool.install(|| {
18 assert!(!LOCAL.is_set());
19 });
20 });
21 }
22
23 #[test]
spawn_scoped_tls_threadpool()24 fn spawn_scoped_tls_threadpool() {
25 LOCAL.set(&Local(42), || {
26 LOCAL.with(|x| {
27 thread::scope(|scope| {
28 let pool = ThreadPoolBuilder::new()
29 .spawn_handler(move |thread| {
30 scope
31 .builder()
32 .spawn(move |_| {
33 // Borrow the same local value in the thread pool.
34 LOCAL.set(x, || thread.run())
35 })
36 .map(|_| ())
37 })
38 .build()
39 .expect("thread pool created");
40
41 // The pool matches our local value.
42 pool.install(|| {
43 assert!(LOCAL.is_set());
44 LOCAL.with(|y| {
45 assert_eq!(x, y);
46 });
47 });
48
49 // If we change our local value, the pool is not affected.
50 LOCAL.set(&Local(-1), || {
51 pool.install(|| {
52 assert!(LOCAL.is_set());
53 LOCAL.with(|y| {
54 assert_eq!(x, y);
55 });
56 });
57 });
58 })
59 .expect("scope threads ok");
60 // `thread::scope` will wait for the threads to exit before returning.
61 });
62 });
63 }
64
65 #[test]
build_scoped_tls_threadpool()66 fn build_scoped_tls_threadpool() {
67 LOCAL.set(&Local(42), || {
68 LOCAL.with(|x| {
69 ThreadPoolBuilder::new()
70 .build_scoped(
71 move |thread| LOCAL.set(x, || thread.run()),
72 |pool| {
73 // The pool matches our local value.
74 pool.install(|| {
75 assert!(LOCAL.is_set());
76 LOCAL.with(|y| {
77 assert_eq!(x, y);
78 });
79 });
80
81 // If we change our local value, the pool is not affected.
82 LOCAL.set(&Local(-1), || {
83 pool.install(|| {
84 assert!(LOCAL.is_set());
85 LOCAL.with(|y| {
86 assert_eq!(x, y);
87 });
88 });
89 });
90 },
91 )
92 .expect("thread pool created");
93 // Internally, `crossbeam::scope` will wait for the threads to exit before returning.
94 });
95 });
96 }
97