Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@
#![feature(allow_internal_unstable)]
#![feature(asm_experimental_arch)]
#![feature(cfg_sanitizer_cfi)]
#![feature(cfg_target_has_atomic)]
#![feature(cfg_target_thread_local)]
#![feature(cfi_encoding)]
#![feature(concat_idents)]
Expand Down
40 changes: 33 additions & 7 deletions library/std/src/sys/thread_local/guard/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,38 @@ use crate::sys::thread_local::key::{LazyKey, set};

#[cfg(target_thread_local)]
pub fn enable() {
use crate::sys::thread_local::destructors;
fn enable_thread() {
static DTORS: LazyKey = LazyKey::new(Some(run_thread));

static DTORS: LazyKey = LazyKey::new(Some(run));
// Setting the key value to something other than NULL will result in the
// destructor being run at thread exit.
unsafe {
set(DTORS.force(), ptr::without_provenance_mut(1));
}

unsafe extern "C" fn run_thread(_: *mut u8) {
run()
}
}

#[cfg(target_has_atomic_load_store = "8")]
fn enable_process() {
use crate::sync::atomic::{AtomicBool, Ordering};
use crate::sys::thread_local::key::at_process_exit;

// Setting the key value to something other than NULL will result in the
// destructor being run at thread exit.
unsafe {
set(DTORS.force(), ptr::without_provenance_mut(1));
static REGISTERED: AtomicBool = AtomicBool::new(false);
if !REGISTERED.swap(true, Ordering::AcqRel) {
unsafe { at_process_exit(run_process) };
}

unsafe extern "C" fn run_process() {
run()
}
}

unsafe extern "C" fn run(_: *mut u8) {
fn run() {
use crate::sys::thread_local::destructors;

unsafe {
destructors::run();
// On platforms with `__cxa_thread_atexit_impl`, `destructors::run`
Expand All @@ -28,6 +49,11 @@ pub fn enable() {
crate::rt::thread_cleanup();
}
}

enable_thread();

#[cfg(target_has_atomic_load_store = "8")]
enable_process();
}

/// On platforms with key-based TLS, the system runs the destructors for us.
Expand Down
4 changes: 4 additions & 0 deletions library/std/src/sys/thread_local/key/sgx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ pub unsafe fn get(key: Key) -> *mut u8 {
pub unsafe fn destroy(key: Key) {
Tls::destroy(AbiKey::from_usize(key))
}

pub unsafe fn at_process_exit(cb: unsafe extern "C" fn()) {
let _ = cb;
}
10 changes: 10 additions & 0 deletions library/std/src/sys/thread_local/key/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,13 @@ pub unsafe fn destroy(key: Key) {
let r = unsafe { libc::pthread_key_delete(key) };
debug_assert_eq!(r, 0);
}

#[inline]
pub unsafe fn at_process_exit(cb: unsafe extern "C" fn()) {
// Miri does not support atexit.
#[cfg(not(miri))]
assert_eq!(unsafe { libc::atexit(mem::transmute(cb)) }, 0);

#[cfg(miri)]
let _ = cb;
}
4 changes: 2 additions & 2 deletions library/std/src/sys/thread_local/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ pub(crate) mod key {
#[cfg(test)]
mod tests;
pub(super) use racy::LazyKey;
pub(super) use unix::{Key, set};
pub(super) use unix::{Key, set, at_process_exit};
#[cfg(any(not(target_thread_local), test))]
pub(super) use unix::get;
use unix::{create, destroy};
Expand All @@ -156,7 +156,7 @@ pub(crate) mod key {
#[cfg(test)]
mod tests;
pub(super) use racy::LazyKey;
pub(super) use sgx::{Key, get, set};
pub(super) use sgx::{Key, get, set, at_process_exit};
use sgx::{create, destroy};
} else if #[cfg(target_os = "xous")] {
mod racy;
Expand Down
Loading