--- a/library/std/src/sys/thread_local/guard/apple.rs +++ b/library/std/src/sys/thread_local/guard/apple.rs @@ -6,7 +6,19 @@ use crate::ptr; use crate::sys::thread_local::destructors; +#[cfg(target_enforce_emulated_tls)] +use crate::sys::thread_local::key::StaticKey; + pub fn enable() { + #[cfg(not(target_enforce_emulated_tls))] + enable_native(); + + #[cfg(target_enforce_emulated_tls)] + enable_emulated(); +} + +#[cfg(not(target_enforce_emulated_tls))] +fn enable_native() { #[thread_local] static REGISTERED: Cell = Cell::new(false); @@ -30,3 +42,24 @@ } } } + +#[cfg(target_enforce_emulated_tls)] +fn enable_emulated() { + // Use StaticKey-based destructor registration for macOS < 10.7 + // This avoids _tlv_atexit which doesn't exist on older systems. + #[thread_local] + static REGISTERED: Cell = Cell::new(false); + + static CLEANUP_KEY: StaticKey = StaticKey::new(Some(run_dtors)); + + if !REGISTERED.replace(true) { + unsafe { CLEANUP_KEY.set(ptr::without_provenance_mut(1)) }; + } + + unsafe extern "C" fn run_dtors(_: *mut u8) { + unsafe { + destructors::run(); + crate::rt::thread_cleanup(); + } + } +}