Improve pthread_cleanup_{push,pop}.
This commit is contained in:
@@ -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)); \
|
||||
|
||||
@@ -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>();
|
||||
|
||||
+5
-5
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user