//! macOS allows registering destructors through _tlv_atexit. But since calling //! it while TLS destructors are running is UB, we still need to keep our own //! list of destructors. use crate::cell::Cell; use crate::ptr; use crate::sys::thread_local::destructors; pub fn enable() { #[thread_local] static REGISTERED: Cell = Cell::new(false); unsafe extern "C" { fn _tlv_atexit(dtor: unsafe extern "C" fn(*mut u8), arg: *mut u8); } if !REGISTERED.replace(true) { // SAFETY: Calling _tlv_atexit while TLS destructors are running is UB. // But as run_dtors is only called after being registered, this point // cannot be reached from it. unsafe { _tlv_atexit(run_dtors, ptr::null_mut()); } } unsafe extern "C" fn run_dtors(_: *mut u8) { unsafe { destructors::run(); crate::rt::thread_cleanup(); } } }