#![cfg(target_thread_local)] #![unstable(feature = "thread_local_internals", issue = "none")] // Simplify dtor registration by using a list of destructors. // The this solution works like the implementation of macOS and // doesn't additional OS support use crate::cell::Cell; use crate::ptr; #[thread_local] static DTORS: Cell<*mut List> = Cell::new(ptr::null_mut()); type List = Vec<(*mut u8, unsafe extern "C" fn(*mut u8))>; pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { if DTORS.get().is_null() { let v: Box = box Vec::new(); DTORS.set(Box::into_raw(v)); } let list: &mut List = &mut *DTORS.get(); list.push((t, dtor)); } // every thread call this function to run through all possible destructors pub unsafe fn run_dtors() { let mut ptr = DTORS.replace(ptr::null_mut()); while !ptr.is_null() { let list = Box::from_raw(ptr); for (ptr, dtor) in list.into_iter() { dtor(ptr); } ptr = DTORS.replace(ptr::null_mut()); } }