#![cfg(target_thread_local)] #![unstable(feature = "thread_local_internals", issue = "none")] // Simplify dtor registration by using a list of destructors. use super::{abi, itron::task}; use crate::cell::Cell; use crate::mem; #[thread_local] static REGISTERED: Cell = Cell::new(false); #[thread_local] static mut DTORS: Vec<(*mut u8, unsafe extern "C" fn(*mut u8))> = Vec::new(); pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { if !REGISTERED.get() { let tid = task::current_task_id_aborting(); // Register `tls_dtor` to make sure the TLS destructors are called // for tasks created by other means than `std::thread` unsafe { abi::SOLID_TLS_AddDestructor(tid as i32, tls_dtor) }; REGISTERED.set(true); } let list = unsafe { &mut DTORS }; list.push((t, dtor)); } pub unsafe fn run_dtors() { let mut list = mem::take(unsafe { &mut DTORS }); while !list.is_empty() { for (ptr, dtor) in list { unsafe { dtor(ptr) }; } list = mem::take(unsafe { &mut DTORS }); } } unsafe extern "C" fn tls_dtor(_unused: *mut u8) { unsafe { run_dtors() }; }