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 target_os = "windows" => {
105 mod windows;
106 pub(crate) use windows::enable;
107 #[cfg(not(target_thread_local))]
108 mod retained;
109 #[cfg(not(target_thread_local))]
110 pub(crate) use retained::{LOCAL_POINTER_NEEDS_DTOR, cleanup_pending};
111 }
112 any(
113 all(target_family = "wasm", not(target_os = "wasi")),
114 target_os = "uefi",
115 target_os = "zkvm",
116 target_os = "trusty",
117 target_os = "vexos",
118 ) => {
119 pub(crate) fn enable() {
120 #[cfg(all(target_family = "wasm", target_feature = "atomics"))]
127 #[allow(unused)]
128 use super::destructors::run;
129 #[allow(unused)]
130 use crate::rt::thread_cleanup;
131 }
132 }
133 any(target_os = "hermit", target_os = "xous") => {
134 pub(crate) fn enable() {}
137 #[cfg(not(target_thread_local))]
138 mod retained;
139 #[cfg(not(target_thread_local))]
140 pub(crate) use retained::{LOCAL_POINTER_NEEDS_DTOR, cleanup_pending};
141 }
142 target_os = "solid_asp3" => {
143 mod solid;
144 pub(crate) use solid::enable;
145 }
146 _ => {
147 mod key;
148 pub(crate) use key::enable;
149 #[cfg(not(target_thread_local))]
150 pub(crate) use key::{LOCAL_POINTER_NEEDS_DTOR, cleanup_pending};
151 }
152 }
153}
154
155pub(crate) mod key {
162 cfg_select! {
163 any(
164 all(not(target_vendor = "apple"), not(target_family = "wasm"), target_family = "unix"),
165 all(not(target_thread_local), target_vendor = "apple"),
166 target_os = "teeos",
167 target_os = "wasi",
168 ) => {
169 mod racy;
170 mod unix;
171 #[cfg(test)]
172 mod tests;
173 pub(super) use racy::LazyKey;
174 #[cfg(any(not(target_thread_local), test))]
175 pub(super) use unix::get;
176 pub(super) use unix::{Key, set};
177 use unix::{create, destroy};
178 }
179 all(not(target_thread_local), target_os = "windows") => {
180 #[cfg(test)]
181 mod tests;
182 mod windows;
183 pub(super) use windows::{Key, LazyKey, get, run_dtors, set};
184 }
185 all(target_vendor = "fortanix", target_env = "sgx") => {
186 mod racy;
187 mod sgx;
188 #[cfg(test)]
189 mod tests;
190 pub(super) use racy::LazyKey;
191 pub(super) use sgx::{Key, get, set};
192 use sgx::{create, destroy};
193 }
194 target_os = "xous" => {
195 mod racy;
196 #[cfg(test)]
197 mod tests;
198 mod xous;
199 pub(super) use racy::LazyKey;
200 pub(crate) use xous::destroy_tls;
201 pub(super) use xous::{Key, get, set};
202 use xous::{create, destroy};
203 }
204 target_os = "motor" => {
205 mod racy;
206 #[cfg(test)]
207 mod tests;
208 pub(super) use moto_rt::tls::{Key, get, set};
209 use moto_rt::tls::{create, destroy};
210 pub(super) use racy::LazyKey;
211 }
212 _ => {}
213 }
214}
215
216#[inline]
220#[allow(dead_code)]
221fn abort_on_dtor_unwind(f: impl FnOnce()) {
222 let guard = DtorUnwindGuard;
224 f();
225 core::mem::forget(guard);
226
227 struct DtorUnwindGuard;
228 impl Drop for DtorUnwindGuard {
229 #[inline]
230 fn drop(&mut self) {
231 rtabort!("thread local panicked on drop");
234 }
235 }
236}