From d069aa8e799803eda24dab270743141a9708fd44 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Fri, 26 May 2023 14:49:21 -0700 Subject: [PATCH] Fix test_pthread_dlopen_many When a thread sync was cancelled (due to a thread exit prior to performing the task) we were treating that as an error, but we should treat that as success. I was able to reproduce the issue by running this test a few times in a row. I confirmed that it did not happen in 160 runs after this fix. Fixes: #18887 --- system/lib/libc/dynlink.c | 20 +++++++++++++++----- test/test_core.py | 1 - 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/system/lib/libc/dynlink.c b/system/lib/libc/dynlink.c index d3ea861731d76..82c7a2d120afa 100644 --- a/system/lib/libc/dynlink.c +++ b/system/lib/libc/dynlink.c @@ -333,11 +333,21 @@ static void do_thread_sync_out(void* arg) { *result = _emscripten_dlsync_self(); } -// Called once _emscripten_proxy_dlsync completes -static void done_thread_sync(void* arg) { +// Called when a thread exists prior to being able to completely sync operation. +// We can just ignore this case and report success. +static void thread_sync_cancelled(void* arg) { + struct promise_result* info = arg; + dbg("thread_sync_cancelled: promise=%p result=%i", info->promise, info->result); + emscripten_promise_resolve(info->promise, EM_PROMISE_FULFILL, NULL); + emscripten_promise_destroy(info->promise); + free(info); +} + +// Called once do_thread_sync completes +static void thread_sync_done(void* arg) { struct promise_result* info = arg; em_promise_t promise = info->promise; - dbg("done_thread_sync: promise=%p result=%i", promise, info->result); + dbg("thread_sync_done: promise=%p result=%i", promise, info->result); if (info->result) { emscripten_promise_resolve(promise, EM_PROMISE_FULFILL, NULL); } else { @@ -389,8 +399,8 @@ int _emscripten_proxy_dlsync_async(pthread_t target_thread, em_promise_t promise int rtn = emscripten_proxy_callback(dlopen_proxying_queue, target_thread, do_thread_sync, - done_thread_sync, - done_thread_sync, + thread_sync_done, + thread_sync_cancelled, info); if (!rtn) { // If we failed to proxy, then the target thread is no longer alive and no diff --git a/test/test_core.py b/test/test_core.py index a5aa6d328ec7e..e1779e02bc436 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -9412,7 +9412,6 @@ def test_pthread_dlopen(self): @needs_dylink @node_pthreads - @disabled('https://github.com/emscripten-core/emscripten/issues/18887') def test_pthread_dlopen_many(self): nthreads = 10 self.emcc_args += ['-Wno-experimental', '-pthread']