std/sys/thread_local/
mod.rs1#![cfg_attr(test, allow(unused))]
18#![doc(hidden)]
19#![forbid(unsafe_op_in_unsafe_fn)]
20#![unstable(
21 feature = "thread_local_internals",
22 reason = "internal details of the thread_local macro",
23 issue = "none"
24)]
25#![deny(
26 clippy::arithmetic_side_effects,
27 clippy::expect_used,
28 clippy::unwrap_used,
29 clippy::indexing_slicing,
30 clippy::panic,
31 clippy::unreachable,
32 clippy::unimplemented,
33 reason = "TLS accesses must not call the global allocator, including via panic (#160930)"
34)]
35
36cfg_select! {
37 any(
38 all(target_family = "wasm", not(target_feature = "atomics"), not(target_os = "wasi")),
39 target_os = "uefi",
40 target_os = "zkvm",
41 target_os = "trusty",
42 target_os = "vexos",
43 ) => {
44 mod no_threads;
45 pub use no_threads::{EagerStorage, LazyStorage, thread_local_inner};
46 pub(crate) use no_threads::{LocalPointer, local_pointer};
47 }
48 target_thread_local => {
49 mod native;
50 pub use native::{EagerStorage, LazyStorage, thread_local_inner};
51 pub(crate) use native::{LocalPointer, local_pointer};
52 }
53 _ => {
54 mod os;
55 pub(crate) use os::{LocalPointer, local_pointer};
56 pub use os::{Storage, thread_local_inner, value_align};
57 }
58}
59
60#[cfg(all(
68 target_thread_local,
69 not(all(target_family = "wasm", not(target_feature = "atomics"), not(target_os = "wasi")))
70))]
71pub(crate) mod destructors {
72 cfg_select! {
73 any(
74 target_os = "linux",
75 target_os = "android",
76 target_os = "fuchsia",
77 target_os = "redox",
78 target_os = "hurd",
79 target_os = "netbsd",
80 target_os = "dragonfly"
81 ) => {
82 mod linux_like;
83 mod list;
84 pub(super) use linux_like::register;
85 pub(super) use list::run;
86 }
87 _ => {
88 mod list;
89 pub(super) use list::register;
90 pub(crate) use list::run;
91 }
92 }
93}
94
95pub(crate) mod guard {
99 cfg_select! {
100 all(target_thread_local, target_vendor = "apple") => {
101 mod apple;
102 pub(crate) use apple::enable;
103 }
104 all(target_thread_local, target_os = "aix") => {
105 mod aix;
106 pub(crate) use aix::enable;
107 }
108 target_os = "windows" => {
109 mod windows;
110 pub(crate) use windows::enable;
111 #[cfg(not(target_thread_local))]
112 mod retained;
113 #[cfg(not(target_thread_local))]
114 pub(crate) use retained::{LOCAL_POINTER_NEEDS_DTOR, cleanup_pending};
115 }
116 any(
117 all(target_family = "wasm", not(target_os = "wasi")),
118 target_os = "uefi",
119 target_os = "zkvm",
120 target_os = "trusty",
121 target_os = "vexos",
122 ) => {
123 pub(crate) fn enable() {
124 #[cfg(all(target_family = "wasm", target_feature = "atomics"))]
131 #[allow(unused)]
132 use super::destructors::run;
133 #[allow(unused)]
134 use crate::rt::thread_cleanup;
135 }
136 }
137 any(target_os = "hermit", target_os = "xous") => {
138 pub(crate) fn enable() {}
141 #[cfg(not(target_thread_local))]
142 mod retained;
143 #[cfg(not(target_thread_local))]
144 pub(crate) use retained::{LOCAL_POINTER_NEEDS_DTOR, cleanup_pending};
145 }
146 target_os = "solid_asp3" => {
147 mod solid;
148 pub(crate) use solid::enable;
149 }
150 _ => {
151 mod key;
152 pub(crate) use key::enable;
153 #[cfg(not(target_thread_local))]
154 pub(crate) use key::{LOCAL_POINTER_NEEDS_DTOR, cleanup_pending};
155 }
156 }
157}
158
159pub(crate) mod key {
166 cfg_select! {
167 any(
168 all(not(target_vendor = "apple"), not(target_family = "wasm"), target_family = "unix"),
169 all(not(target_thread_local), target_vendor = "apple"),
170 target_os = "teeos",
171 target_os = "wasi",
172 ) => {
173 mod racy;
174 mod unix;
175 #[cfg(test)]
176 mod tests;
177 pub(super) use racy::LazyKey;
178 #[cfg(any(not(target_thread_local), test))]
179 pub(super) use unix::get;
180 pub(super) use unix::{Key, set};
181 use unix::{create, destroy};
182 }
183 all(not(target_thread_local), target_os = "windows") => {
184 #[cfg(test)]
185 mod tests;
186 mod windows;
187 pub(super) use windows::{Key, LazyKey, get, run_dtors, set};
188 }
189 all(target_vendor = "fortanix", target_env = "sgx") => {
190 mod racy;
191 mod sgx;
192 #[cfg(test)]
193 mod tests;
194 pub(super) use racy::LazyKey;
195 pub(super) use sgx::{Key, get, set};
196 use sgx::{create, destroy};
197 }
198 target_os = "xous" => {
199 mod racy;
200 #[cfg(test)]
201 mod tests;
202 mod xous;
203 pub(super) use racy::LazyKey;
204 pub(crate) use xous::destroy_tls;
205 pub(super) use xous::{Key, get, set};
206 use xous::{create, destroy};
207 }
208 target_os = "motor" => {
209 mod racy;
210 #[cfg(test)]
211 mod tests;
212 pub(super) use moto_rt::tls::{Key, get, set};
213 use moto_rt::tls::{create, destroy};
214 pub(super) use racy::LazyKey;
215 }
216 _ => {}
217 }
218}
219
220#[inline]
224#[allow(dead_code)]
225fn abort_on_dtor_unwind(f: impl FnOnce()) {
226 let guard = DtorUnwindGuard;
228 f();
229 core::mem::forget(guard);
230
231 struct DtorUnwindGuard;
232 impl Drop for DtorUnwindGuard {
233 #[inline]
234 fn drop(&mut self) {
235 rtabort!("thread local panicked on drop");
238 }
239 }
240}