From 02908cc8b640724f98e5a215bcbc652002b5b3a2 Mon Sep 17 00:00:00 2001 From: Andrea Ciliberti Date: Fri, 21 Apr 2023 20:02:26 +0200 Subject: [PATCH] WIP Implement TLS Destructors --- src/thread.rs | 4 ++++ src/thread_keys.rs | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/thread.rs b/src/thread.rs index 01f2550..3261e71 100644 --- a/src/thread.rs +++ b/src/thread.rs @@ -6,6 +6,8 @@ use std::collections::BTreeMap; use std::ptr; use std::sync::atomic::{AtomicUsize, Ordering}; +use crate::thread_keys; + pub mod attr; /// The main thread's pthread ID @@ -87,6 +89,8 @@ pub unsafe extern "C" fn pthread_create( pthread.is_finished = true; pthread.result.0 = result; + thread_keys::run_local_destructors(); + if pthread.is_detached { // libctru will call threadFree once this thread dies thread_map.remove(&thread_id); diff --git a/src/thread_keys.rs b/src/thread_keys.rs index 5486d4e..9ae254a 100644 --- a/src/thread_keys.rs +++ b/src/thread_keys.rs @@ -19,6 +19,24 @@ fn is_valid_key(key: Key) -> bool { KEYS.read().contains_key(&(key as Key)) } +pub(crate) fn run_local_destructors() { + unsafe { + // We iterate all the thread-local keys set. + // + // When using `std` and the `thread_local!` macro there should be only one key registered here, + // which is the list of keys to destroy. + for (key, value) in LOCALS.iter() { + // We retrieve the destructor for a key from the static list. + if let Some(destructor) = KEYS.read().get(&key) { + // If the destructor is registered for a key, run it. + if let Some(d) = destructor { + d(*value); + } + } + } + }; +} + #[no_mangle] pub unsafe extern "C" fn pthread_key_create( key: *mut libc::pthread_key_t,