Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions library/std/src/sys/exit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ cfg_select! {
}

pub fn exit(code: i32) -> ! {
// Ensure thread local destructors aren't run on any platform.
crate::sys::thread_local::destructors::disable();
cfg_select! {
target_os = "hermit" => unsafe { hermit_abi::exit(code) },
target_os = "linux" => unsafe {
Expand Down
14 changes: 14 additions & 0 deletions library/std/src/sys/thread_local/destructors/list.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
use crate::alloc::System;
use crate::cell::RefCell;
use crate::sync::atomic::{Atomic, Ordering};
use crate::sys::thread_local::guard;

#[thread_local]
static DTORS: RefCell<Vec<(*mut u8, unsafe extern "C" fn(*mut u8)), System>> =
RefCell::new(Vec::new_in(System));

static DISABLE_DTORS: Atomic<bool> = Atomic::<bool>::new(false);

/// Permanently disable running TLS dtors.
pub fn disable() {
DISABLE_DTORS.store(true, Ordering::Release);
}

pub unsafe fn register(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
let Ok(mut dtors) = DTORS.try_borrow_mut() else {
rtabort!("the System allocator may not use TLS with destructors")
Expand All @@ -27,6 +35,12 @@ pub unsafe fn register(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
/// May only be run on thread exit to guarantee that there are no live references
/// to TLS variables while they are destroyed.
pub unsafe fn run() {
if DISABLE_DTORS.load(Ordering::Acquire) {
if let Ok(mut dtors) = DTORS.try_borrow_mut() {
*dtors = Vec::new_in(System);
}
return;
}
loop {
let mut dtors = DTORS.borrow_mut();
match dtors.pop() {
Expand Down
3 changes: 2 additions & 1 deletion library/std/src/sys/thread_local/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,13 @@ pub(crate) mod destructors {
mod linux_like;
mod list;
pub(super) use linux_like::register;
pub(crate) use list::disable;
pub(super) use list::run;
}
_ => {
mod list;
pub(super) use list::register;
pub(crate) use list::run;
pub(crate) use list::{disable, run};
}
}
}
Expand Down
Loading