Skip to content

Conversation

@sbc100
Copy link
Collaborator

@sbc100 sbc100 commented Apr 28, 2025

I'm having some trouble getting this test to pass in #24190 and even having trouble getting to pass on my desktop.

I'm having some trouble getting this test to pass in emscripten-core#24190 and even
having trouble getting to pass on my desktop.
@sbc100
Copy link
Collaborator Author

sbc100 commented Apr 28, 2025

@cwoffenden

@sbc100 sbc100 requested a review from kripken April 28, 2025 20:02
@cwoffenden
Copy link
Collaborator

cwoffenden commented Apr 28, 2025

I'm having some trouble getting this test to pass in #24190 and even having trouble getting to pass on my desktop.

Is it working fine without the changes, only failing with? I should be able to take a look tomorrow.

IIRC, to run locally it needs the browser to have the same prefs/flags settings as I added for the CI, otherwise it won’t playback. Any of the non-interactive tests are designed to run without user clicks, so need the audio to automatically play.

@sbc100
Copy link
Collaborator Author

sbc100 commented Apr 28, 2025

It seems to work in some situation such as when running in headless with --autoplay-policy=no-user-gesture-required.. or when I navigate by clicking a link.

But if I reload the test page after its done, then click to trigger playback, then it doesn't work. My guess is that it never works when the playback is triggered by clicking the on-screen button.

@sbc100
Copy link
Collaborator Author

sbc100 commented Apr 28, 2025

OK to land this ?

case TEST_WAIT_ACQUIRE:
// Release here to acquire in process
emscripten_lock_release(&testLock);
if (!didUnlock) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be an assertion? IIUC this mode should only ever be reached once?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it can actually be a hit continuously until the mode changes. i.e. if the worker is is non responsive then the main thread will just repeatedly call this block forever. We could probably improve the state machine but I'm not sure I want to start messing with this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, can it fail to acquire more than once? I guess maybe...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

emscripten_lock_release doesn't have a return code so it can't really fail. Releasing a lock you don't have I guess is just UB

@sbc100 sbc100 merged commit 0c45bbd into emscripten-core:main Apr 29, 2025
27 of 28 checks passed
@sbc100 sbc100 deleted the audioworklet_emscripten_locks branch April 29, 2025 00:15
@sbc100
Copy link
Collaborator Author

sbc100 commented Apr 29, 2025

I'm having some trouble getting this test to pass in #24190 and even having trouble getting to pass on my desktop.

Is it working fine without the changes, only failing with? I should be able to take a look tomorrow.

IIRC, to run locally it needs the browser to have the same prefs/flags settings as I added for the CI, otherwise it won’t playback. Any of the non-interactive tests are designed to run without user clicks, so need the audio to automatically play.

But this test specifically has a button you can use to start the audio (I suppose in the event that it happens to be run interactively). Can you confirm that the test does now work when audio is started via the button click? Do you have any idea why that is?

@cwoffenden
Copy link
Collaborator

cwoffenden commented Apr 29, 2025

But if I reload the test page after its done, then click to trigger playback, then it doesn't work.

I'm testing it standalone, with the button, and it's working in the latest Emscripten (4.0.8-git from source). My current steps, and also how I wrote it and the other audio tests, in very verbose terms are:

I worked on the file standalone, so from the test/webaudio directory building it with something like:

emcc -O0 -g3 -Wall -sAUDIO_WORKLET -sWASM_WORKERS -sASSERTIONS=2 -sWEBAUDIO_DEBUG -pthread -o index.html audioworklet_emscripten_locks.c

This spat out index.html, etc., as expected in the source directory. I then launch it with emrun, e.g.:

emrun --browser "/Applications/Firefox.app/Contents/MacOS/firefox" index.html

Since it expects to run in the test harness, and exits with emscripten_force_exit() it will only run once. I need to click 'Start playback' for it to run the test, since in this case I'm using regular Firefox with no flags.

Running as a test I'm doing:

test/runner --browser "/Applications/Firefox.app/Contents/MacOS/firefox" browser.test_audio_worklet_emscripten_locks

It does and will only run once, since it exits.

All of the above works checking out from Emcripten's main. I didn't need to add the 10 second lock wait, it should be in a few frames at most, but I can imagine on a VM that might take some real wall-clock time.

I never saw any issues with the multiple lock release that you added the guard around to run once, but don't mind fixing up the state machine so it only runs once and changes state.

Testing on Mac, it works just fine for me also with your audio_worklets_single_file branch on Mac Chrome (135), Firefox (137) and Safari (18.4) building and running as described above. The resulting release build is here:

https://wip.numfum.com/cw/2025-04-29/index.html

(With only index.html, index.js and index.wasm)

To add, in the Emscripten generated HTML you only see limited debug output from the main thread:

main thread releasing lock
TEST_WAIT_INFINTE (from main)
Test success

But in the console (on browsers supporting logging from other threads) you should see:

TEST_HAS_WAIT: 0 (expect: 0)
TEST_TRY_ACQUIRE: 0 (expect: 0)
TEST_WAIT_ACQUIRE_FAIL: 0 (expect: 0)
main thread releasing lock
TEST_WAIT_ACQUIRE: 1  (expect: 1)
TEST_RELEASE: 1 (expect: 1)
TEST_GET_NOW: 1949  (expect: > 0)
TEST_WAIT_INFINTE (from main)
Test success

@sbc100
Copy link
Collaborator Author

sbc100 commented Apr 29, 2025

Wow, thanks for investigating @cwoffenden. I will try to create some through repro steps today and report back to you.

BTW my steps for running just a single test in the browser are this:

$ ./test/runner browser.test_audio_worklet_emscripten_locks --browser=0
$ ./emrun out/test/ --no-browser
$ # Navigate manually to `localhost:6931`

When you run a single test the output always goes in ./out/test BTW. (This is also true for all browser tests actually since they run sequentially).

If you have any more time perhaps you could try patching in #24190 to see if you can see what is going wrong with that test.

I'll also try to report back with repro steps for the failure I think I am seeing on main.

@cwoffenden
Copy link
Collaborator

Following your steps, and with #24190 (and also from main) it runs fine for me. From the test runner I get:

% test/runner browser.test_audio_worklet_emscripten_locks --browser=0 
Running test_browser: (1 tests)

Running the browser tests. Make sure the browser allows popups from localhost.

test_audio_worklet_emscripten_locks (test_browser.browser) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.538s

And from Chrome and FF I get the same results as earlier. I can reload the page without problem, serving from emrun as you do.

I'm out of time today, but what I'll try tomorrow is to add a button to reset the test, and fix up the state machine to only release the lock once. I'll add more logging whilst I'm in there.

Send me whatever failure you have and I'll try to repro. I've built with and without optimisations, various other flags, all works for me.

@sbc100
Copy link
Collaborator Author

sbc100 commented Apr 29, 2025

Following your steps, and with #24190 (and also from main) it runs fine for me. From the test runner I get:

Well that is strange because this test is failing under chrome both locally and in CI with #24190. I wonder if its related to the version of chrome. I'm testing with chrome unstable and the CI uses chrome beta. Which version did you try?

@sbc100
Copy link
Collaborator Author

sbc100 commented Apr 29, 2025

Following your steps, and with #24190 (and also from main) it runs fine for me. From the test runner I get:

Well that is strange because this test is failing under chrome both locally and in CI with #24190. I wonder if its related to the version of chrome. I'm testing with chrome unstable and the CI uses chrome beta. Which version did you try?

BTW that effect I observed looked like them main thread was being blocked somehow (the main loop was not firing) while the AW was doing emscripten_lock_busyspin_wait_acquire.. I can't really think how/why that would be.

@cwoffenden
Copy link
Collaborator

I'm testing with chrome unstable and the CI uses chrome beta. Which version did you try?

Stable: Version 135.0.7049.115 (Official Build) (arm64). I can try with a beta tomorrow; what you you get with FF?

@sbc100
Copy link
Collaborator Author

sbc100 commented Apr 29, 2025

Yes, I can't seem to reproduce the issue on main using FF.

With chrome whenever I start the test using the button is fails:

test.js:528 w:0,t:0x00012304: MainLoop ..

test.js:528 w:0,t:0x00012304: MainLoop ..
test.js:528 w:0,t:0x00012304: MainLoop ..
2
test.js:528 w:0,t:0x00012304: MainLoop ..
test.js:2263 TEST_BEGIN
test.js:528 ww:1: TEST_BEGIN
test.js:528 ww:1: TEST_HAS_WAIT: 0 (expect: 0)
test.js:528 ww:1: TEST_TRY_ACQUIRE: 0 (expect: 0)
test.js:528 ww:1: TEST_WAIT_ACQUIRE_FAIL: 0 (expect: 0)

Here you can see the messages I added to main loop.. it prints a message every second until I press the button.. at which point I never see any more message from the main loop at all.. its like the main thread locks when the button is pressed.

@cwoffenden
Copy link
Collaborator

With chrome whenever I start the test using the button is fails:

Hmm, odd. I'll take a look tomorrow. Does it work for you with Chrome releases?

@sbc100
Copy link
Collaborator Author

sbc100 commented Apr 29, 2025

I found a solution the main thread blocking issue: Produce a few empty frames (5 seems to do it) before trying to do any interaction with the main thread. It seems like main the main thread blocks for the first few process calls?

@cwoffenden
Copy link
Collaborator

Does it block like this if run from the button?

@sbc100
Copy link
Collaborator Author

sbc100 commented Apr 29, 2025

Yes, its is actually specifically when run from the button (and with DevTools open.. although I can'
t remember if I tried with it closed). If I navigate to the test.html via a click the test passes..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants