32 lines
1.1 KiB
Rust
32 lines
1.1 KiB
Rust
//! Implements thread-local destructors that are not associated with any
|
|
//! particular data.
|
|
|
|
#![unstable(feature = "thread_local_internals", issue = "none")]
|
|
#![cfg(target_thread_local)]
|
|
|
|
// Using a per-thread list avoids the problems in synchronizing global state.
|
|
#[thread_local]
|
|
static mut DESTRUCTORS: Vec<(*mut u8, unsafe extern "C" fn(*mut u8))> = Vec::new();
|
|
|
|
// Ensure this can never be inlined because otherwise this may break in dylibs.
|
|
// See #44391.
|
|
#[inline(never)]
|
|
pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
|
|
DESTRUCTORS.push((t, dtor));
|
|
}
|
|
|
|
#[inline(never)] // See comment above
|
|
/// Runs destructors. This should not be called until thread exit.
|
|
pub unsafe fn run_keyless_dtors() {
|
|
// Drop all the destructors.
|
|
//
|
|
// Note: While this is potentially an infinite loop, it *should* be
|
|
// the case that this loop always terminates because we provide the
|
|
// guarantee that a TLS key cannot be set after it is flagged for
|
|
// destruction.
|
|
while let Some((ptr, dtor)) = DESTRUCTORS.pop() {
|
|
(dtor)(ptr);
|
|
}
|
|
// We're done so free the memory.
|
|
DESTRUCTORS = Vec::new();
|
|
}
|