Skip to content

Commit b7da6c1

Browse files
authored
Avoid calling addEventListener in audio worklet (#21897)
1 parent 80798ac commit b7da6c1

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

src/library_wasm_worker.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,12 @@ addToLibrary({
143143
#endif
144144
],
145145
_emscripten_create_wasm_worker__postset: `
146-
if (ENVIRONMENT_IS_WASM_WORKER) {
146+
if (ENVIRONMENT_IS_WASM_WORKER
147+
// AudioWorkletGlobalScope does not contain addEventListener
148+
#if AUDIO_WORKLET
149+
&& !ENVIRONMENT_IS_AUDIO_WORKLET
150+
#endif
151+
) {
147152
_wasmWorkers[0] = this;
148153
addEventListener("message", _wasmWorkerAppendToQueue);
149154
}`,

test/test_browser.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5479,6 +5479,13 @@ def test_audio_worklet(self, args):
54795479
self.skipTest('https://github.com/emscripten-core/emscripten/issues/19161')
54805480
self.btest_exit('webaudio/audioworklet.c', args=['-sAUDIO_WORKLET', '-sWASM_WORKERS'] + args)
54815481

5482+
# Tests that audioworklets and workers can be used at the same time
5483+
@parameterized({
5484+
'': ([],),
5485+
})
5486+
def test_audio_worklet_worker(self, args):
5487+
self.btest('webaudio/audioworklet_worker.c', args=['-sAUDIO_WORKLET', '-sWASM_WORKERS'] + args, expected='1')
5488+
54825489
# Tests that posting functions between the main thread and the audioworklet thread works
54835490
@parameterized({
54845491
'': ([],),

test/webaudio/audioworklet_worker.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#include <emscripten/webaudio.h>
2+
#include <emscripten/wasm_worker.h>
3+
#include <emscripten/threading.h>
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <assert.h>
7+
8+
// Tests that
9+
// - audioworklets and workers can be used at the same time.
10+
// - an audioworklet can emscripten_futex_wake() a waiting worker.
11+
// - global values can be shared between audioworklets and workers.
12+
13+
int workletToWorkerFutexLocation = 0;
14+
int workletToWorkerFlag = 0;
15+
16+
void run_in_worker() {
17+
while (0 == emscripten_futex_wait(&workletToWorkerFutexLocation, 0, 30000)) {
18+
if (workletToWorkerFlag == 1) {
19+
printf("Test success\n");
20+
break;
21+
}
22+
}
23+
24+
#ifdef REPORT_RESULT
25+
REPORT_RESULT(workletToWorkerFlag == 1);
26+
#endif
27+
}
28+
29+
// This event will fire on the audio worklet thread.
30+
void MessageReceivedInAudioWorkletThread() {
31+
assert(emscripten_current_thread_is_audio_worklet());
32+
workletToWorkerFlag = 1;
33+
emscripten_futex_wake(&workletToWorkerFutexLocation, 1);
34+
}
35+
36+
void WebAudioWorkletThreadInitialized(EMSCRIPTEN_WEBAUDIO_T audioContext, EM_BOOL success, void *userData) {
37+
emscripten_audio_worklet_post_function_v(audioContext, MessageReceivedInAudioWorkletThread);
38+
}
39+
40+
uint8_t wasmAudioWorkletStack[4096];
41+
42+
int main() {
43+
emscripten_wasm_worker_t worker = emscripten_malloc_wasm_worker(/*stackSize: */1024);
44+
emscripten_wasm_worker_post_function_v(worker, run_in_worker);
45+
46+
EMSCRIPTEN_WEBAUDIO_T context = emscripten_create_audio_context(0);
47+
emscripten_start_wasm_audio_worklet_thread_async(context, wasmAudioWorkletStack, sizeof(wasmAudioWorkletStack), WebAudioWorkletThreadInitialized, 0);
48+
}

0 commit comments

Comments
 (0)