diff options
Diffstat (limited to 'library/std/src/sys/hermit/thread_local_dtor.rs')
-rw-r--r-- | library/std/src/sys/hermit/thread_local_dtor.rs | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/library/std/src/sys/hermit/thread_local_dtor.rs b/library/std/src/sys/hermit/thread_local_dtor.rs new file mode 100644 index 000000000..9b683fce1 --- /dev/null +++ b/library/std/src/sys/hermit/thread_local_dtor.rs @@ -0,0 +1,36 @@ +#![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()); + } +} |