emscripten
emscripten copied to clipboard
Audio Worklet: emscripten_is_main_browser_thread assertion fails
I sadly cannot share my full code, but I have the following setup:
- I have a concurrent queue, representing jobs: They have audio samples as input data, audio samples as output data, a flag for wether the job is being worked on, and one for wether the job is finished.
- I spawn multiple workers, each looking at the queue, waiting for jobs to come in. They set the working flag to true, do some work, put the results in the output, and set both flags accordingly. The workers use ONNX to do some work, tho I don't think this is relevant.
- I instantiate an audio worklet. The process function creates new jobs for incoming data, and checks for finished jobs, which it puts into its output.
Now, somewhere along the way, this error gets thrown:
7f2ff9c5-3f18-4160-ad31-661df867419b:862 Aborted(Assertion failed: emscripten_is_main_browser_thread(), at: /emsdk/emscripten/system/lib/pthread/emscripten_futex_wait.c,26,futex_wait_main_browser_thread)
abort
___assert_fail
$futex_wait_main_browser_thread
$emscripten_futex_wait
$__wait
$__futexwait
$__lockfile
$fwrite
$std::__2::__stdoutbuf<char>::xsputn(char const*, long)
$std::__2::basic_streambuf<char, std::__2::char_traits<char>>::sputn[abi:ne190106](char const*, long)
$std::__2::ostreambuf_iterator<char, std::__2::char_traits<char>> std::__2::__pad_and_output[abi:ne190106]<char, std::__2::char_traits<char>>(std::__2::ostreambuf_iterator<char, std::__2::char_traits<char>>, char const*, char const*, char const*, std::__2::ios_base&, char)
$std::__2::basic_ostream<char, std::__2::char_traits<char>>& std::__2::__put_character_sequence[abi:ne190106]<char, std::__2::char_traits<char>>(std::__2::basic_ostream<char, std::__2::char_traits<char>>&, char const*, unsigned long)
$std::__2::basic_ostream<char, std::__2::char_traits<char>>& std::__2::operator<<[abi:ne190106]<std::__2::char_traits<char>>(std::__2::basic_ostream<char, std::__2::char_traits<char>>&, char const*)
$myProject::InferenceManager::process_output(float* const*, unsigned long)
$myProject::InferenceManager::process(float const* const*, float* const*, unsigned long)
$myProject::InferenceHandler::process(float const* const*, float* const*, unsigned long)
$MyProcessorProcessor::process(float const* const*, float* const*, unsigned long)
$myProject_process_cb(int, AudioSampleFrame const*, int, AudioSampleFrame*, int, AudioParamFrame const*, void*)
process
Does anyone have an idea what this is about?
I found this issue, which seemed relevant: https://github.com/emscripten-core/emscripten/issues/22962 And this merge request, which fixed something like that: https://github.com/emscripten-core/emscripten/pull/23729
However, this should already be included in the emscripten version that I'm using (4.0.6)? So I think it's not exactly that? Maybe it's something entirely different. Or I'm doing something wrong.
or maybe this is not even caused by AudioWorklet stuff, but maybe by ONNX doing something weird?
Version of emscripten/emsdk: emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 4.0.6 (1ddaae4d2d6dfbb678ecc193bc988820d1fc4633) clang version 21.0.0git (https:/github.com/llvm/llvm-project 4775e6d9099467df9363e1a3cd5950cc3d2fde05) Target: wasm32-unknown-emscripten Thread model: posix
It will fail here:
https://github.com/emscripten-core/emscripten/blob/a53b1a34f0b31f05f2045f2d4aa1343f75180693/system/lib/pthread/emscripten_futex_wait.c#L26
Internally to fwrite() it's eventually ending up here:
https://github.com/emscripten-core/emscripten/blob/a53b1a34f0b31f05f2045f2d4aa1343f75180693/system/lib/pthread/emscripten_futex_wait.c#L132
And since audio worklets don't support atomics wait it's branching as if it were the main thread, but then failing. Are you writing a file with ostream or just trying to put text to stdout?
The fix I did for locks was to support emscripten_lock_busyspin_wait_acquire() and related directly.
@juj @cwoffenden, I guess we need to find a way to make emscripten_futex_wait/wake work with AUDIO_WORKLET? Seems like folks will likely want to be able to use these core C++ data structure with audio worklets?
Oh, I see this is just for stdout? I guess its perhaps not surprising that doesn't work in audio worklets since file I/O in general doesn't work there (since it relies on proxying).
For logging in audio worklets you can use emscripen_out / emscripten_err / emscripten_console_*
@sbc100 The fix would be to make a thread safe version of futex_wait_main_browser_thread () that doesn't use this single global:
https://github.com/emscripten-core/emscripten/blob/a53b1a34f0b31f05f2045f2d4aa1343f75180693/system/lib/pthread/emscripten_futex_wait.c#L18
I know others doing locks for audio demos and the like, and I've just pushed them towards the Emscripten spinlocks for now.