Don't run pthread exit handlers on application exit (#14751)
It should only be executed when a thread is exiting (or when
pthread_exit is explicitly called).
This reverts commit 6d3e78c partially.
diff --git a/src/library_pthread.js b/src/library_pthread.js
index 8fab9a3..4ad34b2 100644
--- a/src/library_pthread.js
+++ b/src/library_pthread.js
@@ -1034,8 +1034,10 @@
__pthread_exit_js__deps: ['exit'],
__pthread_exit_js: function(status) {
- if (!ENVIRONMENT_IS_PTHREAD) _exit(status);
- else PThread.threadExit(status);
+ if (!ENVIRONMENT_IS_PTHREAD) {
+ PThread.runExitHandlers();
+ _exit(status);
+ } else PThread.threadExit(status);
// pthread_exit is marked noReturn, so we must not return from it.
throw 'unwind';
},
diff --git a/src/postamble_minimal.js b/src/postamble_minimal.js
index 0906e77..b2e1389 100644
--- a/src/postamble_minimal.js
+++ b/src/postamble_minimal.js
@@ -24,9 +24,6 @@
var ret = _main();
#if EXIT_RUNTIME
-#if USE_PTHREADS
- PThread.runExitHandlers();
-#endif
callRuntimeCallbacks(__ATEXIT__);
<<< ATEXITS >>>
#endif
@@ -223,7 +220,7 @@
initRuntime(asm);
#if USE_PTHREADS && PTHREAD_POOL_SIZE
if (!ENVIRONMENT_IS_PTHREAD) loadWasmModuleToWorkers();
-#if !PTHREAD_POOL_DELAY_LOAD
+#if !PTHREAD_POOL_DELAY_LOAD
else
#endif
ready();
diff --git a/src/preamble.js b/src/preamble.js
index 1ba0e06..7700b24 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -419,9 +419,6 @@
checkStackCookie();
#endif
#if USE_PTHREADS
-#if EXIT_RUNTIME
- PThread.runExitHandlers();
-#endif
if (ENVIRONMENT_IS_PTHREAD) return; // PThreads reuse the runtime from the main thread.
#endif
#if EXIT_RUNTIME
diff --git a/tests/pthread/test_pthread_setspecific_mainthread.c b/tests/pthread/test_pthread_setspecific_mainthread.c
index bd6bf9f..350aec9 100644
--- a/tests/pthread/test_pthread_setspecific_mainthread.c
+++ b/tests/pthread/test_pthread_setspecific_mainthread.c
@@ -4,12 +4,19 @@
// found in the LICENSE file.
#include <assert.h>
-#include <stdio.h>
#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
void destructor(void* arg) {
+#if defined(RETURN) || defined(EXIT)
+ // The destructors for thread-specific data should only be executed
+ // when a thread exits or when pthread_exit is explicitly called.
+ assert(0 && "pthread key dtor should not be executed on application exit");
+#else
printf("destructor: %ld\n", (long)arg);
assert(arg == (void*)42);
+#endif
}
int main() {
@@ -20,5 +27,12 @@
pthread_setspecific(key, (void*)42);
val = pthread_getspecific(key);
assert(val == (void*)42);
+ printf("done!\n");
+#ifdef RETURN
return 0;
+#elif defined(EXIT)
+ exit(0);
+#else
+ pthread_exit(0);
+#endif
}
diff --git a/tests/pthread/test_pthread_setspecific_mainthread.out b/tests/pthread/test_pthread_setspecific_mainthread.out
index 64ffb72..398e99f 100644
--- a/tests/pthread/test_pthread_setspecific_mainthread.out
+++ b/tests/pthread/test_pthread_setspecific_mainthread.out
@@ -1 +1,2 @@
+done!
destructor: 42
diff --git a/tests/test_core.py b/tests/test_core.py
index d1b8fd6..0ff1a08 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -2335,6 +2335,11 @@
@node_pthreads
def test_pthread_setspecific_mainthread(self):
self.set_setting('EXIT_RUNTIME')
+ print('.. return')
+ self.do_runf(test_file('pthread/test_pthread_setspecific_mainthread.c'), 'done!', emcc_args=['-DRETURN'])
+ print('.. exit')
+ self.do_runf(test_file('pthread/test_pthread_setspecific_mainthread.c'), 'done!', emcc_args=['-DEXIT'])
+ print('.. pthread_exit')
self.do_run_in_out_file_test('pthread/test_pthread_setspecific_mainthread.c')
@node_pthreads