Skip to content

Commit af90642

Browse files
committed
Only use futex_wait_busy on the main browser thread
When I ported this code from JS back in #15742 I mistakenly changed the semantics here. This change restores the previous behaviour of using atomic.wait except in on the main browser thread. The `futex_wait_busy` can clearly only be used a single main thread and is not appropriate for using in cases where there are other threads in the system that also don't support `atomic.wait` (such as IIUC audio worklets). To support that case we would need a different busy wait function that didn't depend on some global singleton like _emscripten_main_thread_futex.
1 parent 6988f7a commit af90642

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

system/lib/pthread/emscripten_futex_wait.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ extern void* _emscripten_main_thread_futex;
1717

1818
int _emscripten_thread_supports_atomics_wait(void);
1919

20-
static int futex_wait_busy(volatile void *addr, uint32_t val, double timeout) {
20+
static int futex_wait_main_browser_thread(volatile void* addr,
21+
uint32_t val,
22+
double timeout) {
2123
// Atomics.wait is not available in the main browser thread, so simulate it
2224
// via busy spinning.
2325
double now = emscripten_get_now();
@@ -119,12 +121,17 @@ int emscripten_futex_wait(volatile void *addr, uint32_t val, double max_wait_ms)
119121
int ret;
120122
emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS_RUNNING, EM_THREAD_STATUS_WAITFUTEX);
121123

122-
// For threads that cannot block (i.e. the main browser thread) we can't use
123-
// __builtin_wasm_memory_atomic_wait32 so we call out the JS function that
124-
// will busy wait.
124+
// For the main browser thread we can't use
125+
// __builtin_wasm_memory_atomic_wait32 so we have busy wait instead.
125126
if (!_emscripten_thread_supports_atomics_wait()) {
126-
ret = futex_wait_busy(addr, val, max_wait_ms);
127-
emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS_WAITFUTEX, EM_THREAD_STATUS_RUNNING);
127+
if (emscripten_is_main_browser_thread()) {
128+
ret = futex_wait_main_browser_thread(addr, val, max_wait_ms);
129+
emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS_WAITFUTEX, EM_THREAD_STATUS_RUNNING);
130+
} else {
131+
// TODO: handle non-main threads that also don't support `atomic.wait`.
132+
// For example AudioWorklet.
133+
assert(0);
134+
}
128135
return ret;
129136
}
130137

0 commit comments

Comments
 (0)