From 272673bd6ce8392ffbae2ae38e00ad388a96e0ca Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Fri, 18 Jun 2021 13:10:32 -0700 Subject: [PATCH] Move `__cxa_thread_atexit` to native code Rather than using a separate JS array use pthread TLS key which get cleaned during `__pthread_tsd_run_dtors`. Followup to #14484 and #14464 which both move more of the cleanup handling for threads and processes onto the native side. --- src/library_pthread.js | 28 ------------------- .../lib/libcxxabi/src/cxa_thread_atexit.cpp | 7 ++++- system/lib/pthread/pthread_create.c | 5 ---- ...n_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.exports | 2 +- ...n_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.imports | 1 - ...main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.sent | 1 - tools/system_libs.py | 1 + 7 files changed, 8 insertions(+), 37 deletions(-) diff --git a/src/library_pthread.js b/src/library_pthread.js index 5d76dd806cd5d..1dee7b13e7422 100644 --- a/src/library_pthread.js +++ b/src/library_pthread.js @@ -52,7 +52,6 @@ var LibraryPThread = { }, // Maps pthread_t to pthread info objects pthreads: {}, - threadExitHandlers: [], // An array of C functions to run when this thread exits. #if PTHREADS_PROFILING createProfilerBlock: function(pthreadPtr) { @@ -985,39 +984,12 @@ var LibraryPThread = { return 0; }, - __pthread_exit_run_handlers__deps: ['exit'], - __pthread_exit_run_handlers: function(status) { - // Called from pthread_exit, either when called explicitly called - // by programmer, or implicitly when leaving the thread main function. - // - // Note: in theory we would like to return any offscreen canvases back to - // the main thread, but if we ever fetched a rendering context for them that - // would not be valid, so we don't try. - -#if PTHREADS_DEBUG - var tb = _pthread_self(); - assert(tb); - err('Pthread 0x' + tb.toString(16) + ' exited.'); -#endif - - while (PThread.threadExitHandlers.length > 0) { - PThread.threadExitHandlers.pop()(); - } - }, - __pthread_detached_exit: function() { // Called at the end of pthread_exit (which occurs also when leaving the // thread main function) if an only if the thread is in a detached state. postMessage({ 'cmd': 'detachedExit' }); }, - __cxa_thread_atexit__sig: 'vii', - __cxa_thread_atexit: function(routine, arg) { - PThread.threadExitHandlers.push(function() { {{{ makeDynCall('vi', 'routine') }}}(arg) }); - }, - __cxa_thread_atexit_impl: '__cxa_thread_atexit', - - // Returns 0 on success, or one of the values -ETIMEDOUT, -EWOULDBLOCK or -EINVAL on error. emscripten_futex_wait__deps: ['emscripten_main_thread_process_queued_calls'], emscripten_futex_wait: function(addr, val, timeout) { diff --git a/system/lib/libcxxabi/src/cxa_thread_atexit.cpp b/system/lib/libcxxabi/src/cxa_thread_atexit.cpp index a940eaf2f9cc3..6510e7debd04b 100644 --- a/system/lib/libcxxabi/src/cxa_thread_atexit.cpp +++ b/system/lib/libcxxabi/src/cxa_thread_atexit.cpp @@ -112,9 +112,14 @@ extern "C" { #ifdef HAVE___CXA_THREAD_ATEXIT_IMPL return __cxa_thread_atexit_impl(dtor, obj, dso_symbol); #else +#ifndef __EMSCRIPTEN__ + // Emscripten doesn't fully support weak undefined symbols yet + // https://github.com/emscripten-core/emscripten/issues/12819 if (__cxa_thread_atexit_impl) { return __cxa_thread_atexit_impl(dtor, obj, dso_symbol); - } else { + } else +#endif + { // Initialize the dtors std::__libcpp_tls_key (uses __cxa_guard_*() for // one-time initialization and __cxa_atexit() for destruction) static DtorsManager manager; diff --git a/system/lib/pthread/pthread_create.c b/system/lib/pthread/pthread_create.c index bc50466d86b9d..c6e7935e656a9 100644 --- a/system/lib/pthread/pthread_create.c +++ b/system/lib/pthread/pthread_create.c @@ -21,7 +21,6 @@ extern int __pthread_create_js(struct pthread *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); extern void _emscripten_thread_init(int, int, int); -extern void __pthread_exit_run_handlers(); extern void __pthread_detached_exit(); extern void* _emscripten_tls_base(); extern int8_t __dso_handle; @@ -125,10 +124,6 @@ void _emscripten_thread_exit(void* result) { // Run any handlers registered with pthread_cleanup_push __run_cleanup_handlers(); - // Run any JS thread exit handlers (for C++ programs this includes any - // functions registered with __cxa_thread_atexit). - __pthread_exit_run_handlers(); - // Call into the musl function that runs destructors of all thread-specific data. __pthread_tsd_run_dtors(); diff --git a/tests/other/metadce/minimal_main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.exports b/tests/other/metadce/minimal_main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.exports index 8bbfd29999464..4460c5af8dd38 100644 --- a/tests/other/metadce/minimal_main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.exports +++ b/tests/other/metadce/minimal_main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.exports @@ -13,7 +13,7 @@ L M N O -P +u v w x diff --git a/tests/other/metadce/minimal_main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.imports b/tests/other/metadce/minimal_main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.imports index 014f2e2290126..9479133a56d79 100644 --- a/tests/other/metadce/minimal_main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.imports +++ b/tests/other/metadce/minimal_main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.imports @@ -18,4 +18,3 @@ a.q a.r a.s a.t -a.u diff --git a/tests/other/metadce/minimal_main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.sent b/tests/other/metadce/minimal_main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.sent index ad11ff431eda4..b64b08c98af4d 100644 --- a/tests/other/metadce/minimal_main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.sent +++ b/tests/other/metadce/minimal_main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.sent @@ -18,4 +18,3 @@ q r s t -u diff --git a/tools/system_libs.py b/tools/system_libs.py index 0110efed846d6..4af351262cdb0 100644 --- a/tools/system_libs.py +++ b/tools/system_libs.py @@ -986,6 +986,7 @@ def get_files(self): 'cxa_guard.cpp', 'cxa_handlers.cpp', 'cxa_virtual.cpp', + 'cxa_thread_atexit.cpp', 'fallback_malloc.cpp', 'stdlib_new_delete.cpp', 'stdlib_exception.cpp',