Re-throw exception on main thread in PROXY_TO_PTHREAD mode Without this, an exception on the prozied main thread will be swallows and the browser main (or node main) thread will just keep running.
diff --git a/emcc.py b/emcc.py index 8d6f8f4..27a6fd9 100755 --- a/emcc.py +++ b/emcc.py
@@ -1615,7 +1615,7 @@ building.user_requested_exports += ['exit'] if shared.Settings.PROXY_TO_PTHREAD: - shared.Settings.EXPORTED_FUNCTIONS += ['_emscripten_proxy_main'] + shared.Settings.EXPORTED_FUNCTIONS += ['_emscripten_proxy_main', '_emscripten_proxy_main_thread_id'] # pthread stack setup and other necessary utilities def include_and_export(name):
diff --git a/src/library_pthread.js b/src/library_pthread.js index e9816bb..cc9914c 100644 --- a/src/library_pthread.js +++ b/src/library_pthread.js
@@ -8,6 +8,9 @@ $PThread__postset: 'if (!ENVIRONMENT_IS_PTHREAD) PThread.initMainThreadBlock();', $PThread__deps: ['_emscripten_thread_init', 'emscripten_register_main_browser_thread_id', +#if PROXY_TO_PTHREAD + 'emscripten_proxy_main_thread_id', +#endif '$ERRNO_CODES', 'emscripten_futex_wake', '$killThread', '$cancelThread', '$cleanupThread', #if USE_ASAN || USE_LSAN @@ -369,6 +372,14 @@ worker.onerror = function(e) { err('pthread sent an error! ' + e.filename + ':' + e.lineno + ': ' + e.message); +#if PROXY_TO_PTHREAD + // If the worker running the main thread generates an error, we want + // it to take down the main browser thread too. Especially on node + // we want the process to exit in that case. + if (worker.pthread && worker.pthread.thread === _emscripten_proxy_main_thread_id()) { + throw e; + } +#endif }; #if ENVIRONMENT_MAY_BE_NODE
diff --git a/system/include/emscripten/threading.h b/system/include/emscripten/threading.h index aaf02b0..cf04619 100644 --- a/system/include/emscripten/threading.h +++ b/system/include/emscripten/threading.h
@@ -363,6 +363,8 @@ pthread_t emscripten_main_browser_thread_id(void); +pthread_t emscripten_proxy_main_thread_id(void); + // Synchronously sleeps the calling thread for the given number of milliseconds. // Note: Calling this on the main browser thread is _very_ _very_ bad for // application logic throttling, because it does not save any battery, it will
diff --git a/system/lib/pthread/library_pthread.c b/system/lib/pthread/library_pthread.c index 415b31e..e62d87f 100644 --- a/system/lib/pthread/library_pthread.c +++ b/system/lib/pthread/library_pthread.c
@@ -911,17 +911,22 @@ // the main thread is waiting, we wake it up before waking up any workers. EMSCRIPTEN_KEEPALIVE void* _emscripten_main_thread_futex; +static pthread_t _main_thread; static int _main_argc; static char** _main_argv; extern int __call_main(int argc, char** argv); -static void* _main_thread(void* param) { +static void* _main_thread_entry(void* param) { // This is the main runtime thread for the application. emscripten_set_thread_name(pthread_self(), "Application main thread"); return (void*)__call_main(_main_argc, _main_argv); } +pthread_t emscripten_proxy_main_thread_id() { + return _main_thread; +} + int emscripten_proxy_main(int argc, char** argv) { pthread_attr_t attr; pthread_attr_init(&attr); @@ -934,8 +939,7 @@ emscripten_pthread_attr_settransferredcanvases(&attr, (const char*)-1); _main_argc = argc; _main_argv = argv; - pthread_t thread; - int rc = pthread_create(&thread, &attr, _main_thread, NULL); + int rc = pthread_create(&_main_thread, &attr, _main_thread_entry, NULL); pthread_attr_destroy(&attr); return rc; }
diff --git a/tests/core/pthread/test_proxy_to_pthread_exception.c b/tests/core/pthread/test_proxy_to_pthread_exception.c new file mode 100644 index 0000000..e747f2e --- /dev/null +++ b/tests/core/pthread/test_proxy_to_pthread_exception.c
@@ -0,0 +1,6 @@ +#include <emscripten.h> + +int main() { + EM_ASM(missingFunc()); + return 0; +}
diff --git a/tests/core/pthread/test_proxy_to_pthread_exception.out b/tests/core/pthread/test_proxy_to_pthread_exception.out new file mode 100644 index 0000000..1e80697 --- /dev/null +++ b/tests/core/pthread/test_proxy_to_pthread_exception.out
@@ -0,0 +1 @@ +ReferenceError: missingFunc is not defined
diff --git a/tests/test_core.py b/tests/test_core.py index e48211f..c69b993 100644 --- a/tests/test_core.py +++ b/tests/test_core.py
@@ -8117,6 +8117,12 @@ self.emcc_args += ['--pre-js', path_from_root('tests', 'core', 'pthread', 'test_pthread_exit_runtime.pre.js')] self.do_run_in_out_file_test('tests', 'core', 'pthread', 'test_pthread_exit_runtime.c', assert_returncode=43) + @node_pthreads + def test_proxy_to_pthread_exception(self): + self.set_setting('PROXY_TO_PTHREAD') + self.set_setting('PTHREAD_POOL_SIZE', '1') + self.do_run_in_out_file_test('tests', 'core', 'pthread', 'test_proxy_to_pthread_exception.c', assert_returncode=NON_ZERO) + def test_emscripten_atomics_stub(self): self.do_run_in_out_file_test('tests', 'core', 'pthread', 'emscripten_atomics.c')