From e47e5285cdc140d9c1bd778f4d33d58f0fb13af2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sat, 22 Nov 2025 14:05:47 +0200 Subject: [PATCH 1/3] When Atomics.wait() is polyfilled, do not attempt to use it in _emscripten_thread_mailbox_await(), since the polyfill will not work there. This is take two at fixing #25494. --- src/lib/libatomic.js | 3 ++- src/lib/libpthread.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib/libatomic.js b/src/lib/libatomic.js index bad0b05a7950e..309075b59c0bc 100644 --- a/src/lib/libatomic.js +++ b/src/lib/libatomic.js @@ -22,7 +22,8 @@ addToLibrary({ // https://github.com/tc39/proposal-atomics-wait-async/blob/master/PROPOSAL.md // This polyfill performs polling with setTimeout() to observe a change in the // target memory location. - $polyfillWaitAsync__postset: `if (!Atomics.waitAsync || (globalThis.navigator?.userAgent && Number((navigator.userAgent.match(/Chrom(e|ium)\\/([0-9]+)\\./)||[])[2]) < 91)) { + $polyfillWaitAsync__postset: `Atomics.waitAsyncPolyfilled = (!Atomics.waitAsync || (globalThis.navigator?.userAgent && Number((navigator.userAgent.match(/Chrom(e|ium)\\/([0-9]+)\\./)||[])[2]) < 91)); +if (Atomics.waitAsyncPolyfilled) { let __Atomics_waitAsyncAddresses = [/*[i32a, index, value, maxWaitMilliseconds, promiseResolve]*/]; function __Atomics_pollWaitAsyncAddresses() { let now = performance.now(); diff --git a/src/lib/libpthread.js b/src/lib/libpthread.js index 83f0501a52f46..7850b0c79adb6 100644 --- a/src/lib/libpthread.js +++ b/src/lib/libpthread.js @@ -1263,7 +1263,7 @@ var LibraryPThread = { _emscripten_thread_mailbox_await__deps: ['$checkMailbox'], _emscripten_thread_mailbox_await: (pthread_ptr) => { - if (Atomics.waitAsync) { + if (!Atomics.waitAsyncPolyfilled) { // Wait on the pthread's initial self-pointer field because it is easy and // safe to access from sending threads that need to notify the waiting // thread. From 4fdfd6e6e3d67120ddbc7ea1e9251038117cb47c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sat, 22 Nov 2025 21:47:37 +0200 Subject: [PATCH 2/3] Add dependency --- src/lib/libatomic.js | 5 +++-- src/lib/libpthread.js | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lib/libatomic.js b/src/lib/libatomic.js index 309075b59c0bc..3d8b53ccacad2 100644 --- a/src/lib/libatomic.js +++ b/src/lib/libatomic.js @@ -22,8 +22,9 @@ addToLibrary({ // https://github.com/tc39/proposal-atomics-wait-async/blob/master/PROPOSAL.md // This polyfill performs polling with setTimeout() to observe a change in the // target memory location. - $polyfillWaitAsync__postset: `Atomics.waitAsyncPolyfilled = (!Atomics.waitAsync || (globalThis.navigator?.userAgent && Number((navigator.userAgent.match(/Chrom(e|ium)\\/([0-9]+)\\./)||[])[2]) < 91)); -if (Atomics.waitAsyncPolyfilled) { + $waitAsyncPolyfilled: `Atomics.waitAsyncPolyfilled = (!Atomics.waitAsync || (globalThis.navigator?.userAgent && Number((navigator.userAgent.match(/Chrom(e|ium)\\/([0-9]+)\\./)||[])[2]) < 91));`, + $polyfillWaitAsync__deps: ['$waitAsyncPolyfilled'], + $polyfillWaitAsync__postset: `if (Atomics.waitAsyncPolyfilled) { let __Atomics_waitAsyncAddresses = [/*[i32a, index, value, maxWaitMilliseconds, promiseResolve]*/]; function __Atomics_pollWaitAsyncAddresses() { let now = performance.now(); diff --git a/src/lib/libpthread.js b/src/lib/libpthread.js index 7850b0c79adb6..ae8a15654b719 100644 --- a/src/lib/libpthread.js +++ b/src/lib/libpthread.js @@ -1261,7 +1261,7 @@ var LibraryPThread = { } }), - _emscripten_thread_mailbox_await__deps: ['$checkMailbox'], + _emscripten_thread_mailbox_await__deps: ['$checkMailbox', '$waitAsyncPolyfilled'], _emscripten_thread_mailbox_await: (pthread_ptr) => { if (!Atomics.waitAsyncPolyfilled) { // Wait on the pthread's initial self-pointer field because it is easy and From ab34b32767fa98c5227588d32138a114c70832bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Sat, 22 Nov 2025 22:48:15 +0200 Subject: [PATCH 3/3] review --- src/lib/libatomic.js | 4 ++-- src/lib/libpthread.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/libatomic.js b/src/lib/libatomic.js index 3d8b53ccacad2..f83f8c635c1ae 100644 --- a/src/lib/libatomic.js +++ b/src/lib/libatomic.js @@ -22,9 +22,9 @@ addToLibrary({ // https://github.com/tc39/proposal-atomics-wait-async/blob/master/PROPOSAL.md // This polyfill performs polling with setTimeout() to observe a change in the // target memory location. - $waitAsyncPolyfilled: `Atomics.waitAsyncPolyfilled = (!Atomics.waitAsync || (globalThis.navigator?.userAgent && Number((navigator.userAgent.match(/Chrom(e|ium)\\/([0-9]+)\\./)||[])[2]) < 91));`, + $waitAsyncPolyfilled: '=(!Atomics.waitAsync || (globalThis.navigator?.userAgent && Number((navigator.userAgent.match(/Chrom(e|ium)\\/([0-9]+)\\./)||[])[2]) < 91));', $polyfillWaitAsync__deps: ['$waitAsyncPolyfilled'], - $polyfillWaitAsync__postset: `if (Atomics.waitAsyncPolyfilled) { + $polyfillWaitAsync__postset: `if (waitAsyncPolyfilled) { let __Atomics_waitAsyncAddresses = [/*[i32a, index, value, maxWaitMilliseconds, promiseResolve]*/]; function __Atomics_pollWaitAsyncAddresses() { let now = performance.now(); diff --git a/src/lib/libpthread.js b/src/lib/libpthread.js index ae8a15654b719..29a30985b1354 100644 --- a/src/lib/libpthread.js +++ b/src/lib/libpthread.js @@ -1263,7 +1263,7 @@ var LibraryPThread = { _emscripten_thread_mailbox_await__deps: ['$checkMailbox', '$waitAsyncPolyfilled'], _emscripten_thread_mailbox_await: (pthread_ptr) => { - if (!Atomics.waitAsyncPolyfilled) { + if (!waitAsyncPolyfilled) { // Wait on the pthread's initial self-pointer field because it is easy and // safe to access from sending threads that need to notify the waiting // thread.