Skip to content
Snippets Groups Projects
Verified Commit 8d9dd0df authored by Jacob Lorentzon's avatar Jacob Lorentzon :speech_balloon:
Browse files

Improve pthread_cleanup_{push,pop}.

parent 714e7311
No related branches found
No related tags found
No related merge requests found
...@@ -4,6 +4,7 @@ language = "C" ...@@ -4,6 +4,7 @@ language = "C"
style = "type" style = "type"
no_includes = true no_includes = true
cpp_compat = true cpp_compat = true
# TODO: Any better way to implement pthread_cleanup_push/pthread_cleanup_pop?
after_includes = """ after_includes = """
#define PTHREAD_COND_INITIALIZER ((pthread_cond_t){0}) #define PTHREAD_COND_INITIALIZER ((pthread_cond_t){0})
#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t){0}) #define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t){0})
...@@ -11,17 +12,15 @@ after_includes = """ ...@@ -11,17 +12,15 @@ after_includes = """
#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t){0}) #define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t){0})
#define pthread_cleanup_push(routine, arg) do { \ #define pthread_cleanup_push(routine, arg) do { \
do { \ struct { \
struct { \ void (*routine)(void *); \
void (*routine)(void *); \ void *arg; \
void *arg; \ void *prev; \
void *prev; \ } __relibc_internal_pthread_ll_entry = { \
} __relibc_internal_pthread_ll_entry = { \ .routine = (routine), \
.routine = (routine), \ .arg = (arg), \
.arg = (arg), \ }; \
}; \ __relibc_internal_pthread_cleanup_push(&__relibc_internal_pthread_ll_entry);
__relibc_internal_pthread_cleanup_push(&__relibc_internal_pthread_ll_entry); \
} while(0)
#define pthread_cleanup_pop(execute) \ #define pthread_cleanup_pop(execute) \
__relibc_internal_pthread_cleanup_pop((execute)); \ __relibc_internal_pthread_cleanup_pop((execute)); \
......
...@@ -222,6 +222,8 @@ pub(crate) struct CleanupLinkedListEntry { ...@@ -222,6 +222,8 @@ pub(crate) struct CleanupLinkedListEntry {
#[thread_local] #[thread_local]
pub(crate) static CLEANUP_LL_HEAD: Cell<*const CleanupLinkedListEntry> = Cell::new(core::ptr::null()); pub(crate) static CLEANUP_LL_HEAD: Cell<*const CleanupLinkedListEntry> = Cell::new(core::ptr::null());
// TODO: unwind? setjmp/longjmp?
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn __relibc_internal_pthread_cleanup_push(new_entry: *mut c_void) { pub unsafe extern "C" fn __relibc_internal_pthread_cleanup_push(new_entry: *mut c_void) {
let new_entry = &mut *new_entry.cast::<CleanupLinkedListEntry>(); let new_entry = &mut *new_entry.cast::<CleanupLinkedListEntry>();
......
...@@ -265,6 +265,11 @@ pub unsafe fn testcancel() { ...@@ -265,6 +265,11 @@ pub unsafe fn testcancel() {
} }
pub unsafe fn exit_current_thread(retval: Retval) -> ! { 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"); let this = current_thread().expect("failed to obtain current thread when exiting");
if this.flags.load(Ordering::Acquire) & PthreadFlags::DETACHED.bits() != 0 { if this.flags.load(Ordering::Acquire) & PthreadFlags::DETACHED.bits() != 0 {
...@@ -295,11 +300,6 @@ unsafe extern "C" fn cancel_sighandler(_: c_int) { ...@@ -295,11 +300,6 @@ unsafe extern "C" fn cancel_sighandler(_: c_int) {
cancel_current_thread(); cancel_current_thread();
} }
unsafe fn 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 // Terminate the thread
exit_current_thread(Retval(header::PTHREAD_CANCELED)); exit_current_thread(Retval(header::PTHREAD_CANCELED));
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment