From 8d9dd0df459db5b8850c51a9f1d9011bb1cd5f3d Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Thu, 27 Apr 2023 13:23:59 +0200 Subject: [PATCH] Improve pthread_cleanup_{push,pop}. --- src/header/bits_pthread/cbindgen.toml | 21 ++++++++++----------- src/header/pthread/mod.rs | 2 ++ src/pthread/mod.rs | 10 +++++----- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/header/bits_pthread/cbindgen.toml b/src/header/bits_pthread/cbindgen.toml index cea35466..34956c00 100644 --- a/src/header/bits_pthread/cbindgen.toml +++ b/src/header/bits_pthread/cbindgen.toml @@ -4,6 +4,7 @@ language = "C" style = "type" no_includes = true cpp_compat = true +# TODO: Any better way to implement pthread_cleanup_push/pthread_cleanup_pop? after_includes = """ #define PTHREAD_COND_INITIALIZER ((pthread_cond_t){0}) #define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t){0}) @@ -11,17 +12,15 @@ after_includes = """ #define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t){0}) #define pthread_cleanup_push(routine, arg) do { \ - do { \ - struct { \ - void (*routine)(void *); \ - void *arg; \ - void *prev; \ - } __relibc_internal_pthread_ll_entry = { \ - .routine = (routine), \ - .arg = (arg), \ - }; \ - __relibc_internal_pthread_cleanup_push(&__relibc_internal_pthread_ll_entry); \ - } while(0) + struct { \ + void (*routine)(void *); \ + void *arg; \ + void *prev; \ + } __relibc_internal_pthread_ll_entry = { \ + .routine = (routine), \ + .arg = (arg), \ + }; \ + __relibc_internal_pthread_cleanup_push(&__relibc_internal_pthread_ll_entry); #define pthread_cleanup_pop(execute) \ __relibc_internal_pthread_cleanup_pop((execute)); \ diff --git a/src/header/pthread/mod.rs b/src/header/pthread/mod.rs index 81e026ef..afad09fd 100644 --- a/src/header/pthread/mod.rs +++ b/src/header/pthread/mod.rs @@ -222,6 +222,8 @@ pub(crate) struct CleanupLinkedListEntry { #[thread_local] pub(crate) static CLEANUP_LL_HEAD: Cell<*const CleanupLinkedListEntry> = Cell::new(core::ptr::null()); +// TODO: unwind? setjmp/longjmp? + #[no_mangle] pub unsafe extern "C" fn __relibc_internal_pthread_cleanup_push(new_entry: *mut c_void) { let new_entry = &mut *new_entry.cast::<CleanupLinkedListEntry>(); diff --git a/src/pthread/mod.rs b/src/pthread/mod.rs index 1d09c62e..a8766db8 100644 --- a/src/pthread/mod.rs +++ b/src/pthread/mod.rs @@ -265,6 +265,11 @@ pub unsafe fn testcancel() { } pub unsafe fn exit_current_thread(retval: Retval) -> ! { + // Run pthread_cleanup_push/pthread_cleanup_pop destructors. + header::run_destructor_stack(); + + header::tls::run_all_destructors(); + let this = current_thread().expect("failed to obtain current thread when exiting"); if this.flags.load(Ordering::Acquire) & PthreadFlags::DETACHED.bits() != 0 { @@ -295,11 +300,6 @@ unsafe extern "C" fn cancel_sighandler(_: c_int) { cancel_current_thread(); } unsafe fn cancel_current_thread() { - // Run pthread_cleanup_push/pthread_cleanup_pop destructors. - header::run_destructor_stack(); - - header::tls::run_all_destructors(); - // Terminate the thread exit_current_thread(Retval(header::PTHREAD_CANCELED)); } -- GitLab