From f5593035dc9b90d88a9d38a76e008ae1b610936f Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 31 Jul 2026 18:38:06 -0700 Subject: [PATCH] Do not error on messages from terminated workers Messages can generally arrive after a worker has terminated if the message being sent races with the thread shutting down. This does not cause any problems, and the logging made it possible for expected test output to be interrupted. --- src/lib/libpthread.js | 7 +------ test/test_other.py | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/lib/libpthread.js b/src/lib/libpthread.js index 2f65bfa8ae739..5824c847530e5 100644 --- a/src/lib/libpthread.js +++ b/src/lib/libpthread.js @@ -601,12 +601,7 @@ var LibraryPThread = { // the worker is now dead and we don't want to hear from it again, so we stub // out its message handler here. This avoids having to check in each of // the onmessage handlers if the message was coming from a valid worker. - worker.onmessage = (e) => { -#if ASSERTIONS - var cmd = e.data.cmd; - err(`received "${cmd}" command from terminated worker: ${worker.workerID}`); -#endif - }; + worker.onmessage = () => {}; }, _emscripten_thread_cleanup: (thread) => { diff --git a/test/test_other.py b/test/test_other.py index df63abf035d05..8991cd88e3a4e 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -13446,6 +13446,42 @@ def test_pthread_callback_alignment(self): def test_pthread_join_interrupted(self): self.do_runf('pthread/test_pthread_join_interrupted.c', cflags=['-pthread']) + @requires_pthreads + def test_pthread_proxied_join_and_exit(self): + # Check that expected lifecycle messages coming from terminated workers do + # not log warnings. + create_file('test_pthread_proxied_join_and_exit.c', r''' + #include + #include + + void* thread_main(void* arg) { + emscripten_console_log("worker"); + return NULL; + } + + int main() { + pthread_t t1, t2, t3; + pthread_create(&t1, NULL, thread_main, NULL); + pthread_create(&t2, NULL, thread_main, NULL); + pthread_create(&t3, NULL, thread_main, NULL); + + pthread_join(t1, NULL); + pthread_join(t2, NULL); + pthread_join(t3, NULL); + + return 0; + } + ''') + + out_js = self.in_dir('test_pthread_proxied_join_and_exit.js') + self.run_process([ + EMCC, '-pthread', '-sPROXY_TO_PTHREAD', '-sEXIT_RUNTIME', '-sASSERTIONS', + 'test_pthread_proxied_join_and_exit.c', '-o', out_js, + ]) + + output = self.run_js(out_js) + self.assertEqual(output.splitlines(), ['worker', 'worker', 'worker']) + @requires_node_26 def test_growable_arraybuffers(self): self.do_runf('hello_world.c',