blob: 9b683fce157488df8d26ee08184e278578e5c17b [file] [log] [blame]
#![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<List> = 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());
}
}