From ed9f2a397b055333e1cd5a0cb611d73962d72352 Mon Sep 17 00:00:00 2001 From: stephenduong1004 Date: Tue, 31 Mar 2026 16:01:08 -0400 Subject: [PATCH] Fix infinite hang in emscripten_futex_wait This bug was introduced in #26471. This PR is based on #26586. Thanks @stephenduong1004! --- system/lib/pthread/emscripten_futex_wait.c | 2 +- .../{emscripten_futexes.c => emscripten_futex_api_basics.c} | 4 ++++ ...emscripten_futexes.out => emscripten_futex_api_basics.out} | 0 test/test_core.py | 4 ++-- 4 files changed, 7 insertions(+), 3 deletions(-) rename test/core/pthread/{emscripten_futexes.c => emscripten_futex_api_basics.c} (89%) rename test/core/pthread/{emscripten_futexes.out => emscripten_futex_api_basics.out} (100%) diff --git a/system/lib/pthread/emscripten_futex_wait.c b/system/lib/pthread/emscripten_futex_wait.c index cf2b01c8df6a5..291ecc18df01f 100644 --- a/system/lib/pthread/emscripten_futex_wait.c +++ b/system/lib/pthread/emscripten_futex_wait.c @@ -224,7 +224,7 @@ int emscripten_futex_wait(volatile void *addr, uint32_t val, double max_wait_ms) } // If remainder_ns is negative it means we want wait forever, and we don't // need to decrement remainder_ns in that case. - if (wakeup_interval && remainder_ns > 0) { + if (wakeup_interval && remainder_ns >= 0) { remainder_ns -= wakeup_interval; if (remainder_ns <= 0) { break; diff --git a/test/core/pthread/emscripten_futexes.c b/test/core/pthread/emscripten_futex_api_basics.c similarity index 89% rename from test/core/pthread/emscripten_futexes.c rename to test/core/pthread/emscripten_futex_api_basics.c index c97a680785491..9786d306d810d 100644 --- a/test/core/pthread/emscripten_futexes.c +++ b/test/core/pthread/emscripten_futex_api_basics.c @@ -14,6 +14,10 @@ int main() { rc = emscripten_futex_wait(&futex_value, futex_value, 1); assert(rc == -ETIMEDOUT); + // As should this. + rc = emscripten_futex_wait(&futex_value, futex_value, 0); + assert(rc == -ETIMEDOUT); + // Check that this thread has removed itself from the wait queue. rc = emscripten_futex_wake(&futex_value, INT_MAX); assert(rc == 0); diff --git a/test/core/pthread/emscripten_futexes.out b/test/core/pthread/emscripten_futex_api_basics.out similarity index 100% rename from test/core/pthread/emscripten_futexes.out rename to test/core/pthread/emscripten_futex_api_basics.out diff --git a/test/test_core.py b/test/test_core.py index de3238532da5c..c3f4e7fa1ed17 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -9251,10 +9251,10 @@ def test_emscripten_atomics(self): self.do_core_test('pthread/emscripten_atomics.c', cflags=['-pthread']) @requires_pthreads - def test_emscripten_futexes(self): + def test_emscripten_futex_api_basics(self): # This test explicitly checks behavior of passing NULL to emscripten_futex_wake() so # need to disable the `-Wno-nonnull` to disabled these warnings. - self.do_core_test('pthread/emscripten_futexes.c', cflags=['-pthread', '-Wno-nonnull']) + self.do_core_test('pthread/emscripten_futex_api_basics.c', cflags=['-pthread', '-Wno-nonnull']) @requires_pthreads def test_stdio_locking(self):