Repository navigation
fix(libSceAudioOut): park guest audio calls at exit before the port tables are destroyed - #6000
Conversation
…ables are destroyed The library registered no shutdown callback, so a guest mixer thread kept calling sceAudioOut2ContextPush while exit ran the static destructors and mixed from the freed port table (boykopovar#5864). Exports that read the port tables or output audio now hold a guard: once exit starts they park the thread with LibcAwaitExit_nid_postfix, and the shutdown callback waits for the calls already inside. A push waiting for a grain from sceAudioOut2ContextAdvance also wakes on the shutdown token, so the callback does not wait for an advance that is parked.
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
|
Regression: after this PR the Peace Walker launcher exits before it starts the game (LoadExec hand-over)Title: METAL GEAR SOLID: Peace Walker (PPSA18216), Master Collection launcher, What happensOn The converted game executable ( CheckThe only change between those two that touches shutdown is this PR. With e7219e4 reverted on top of d92a8da (plus some unrelated AGC PRs), the same launcher run hands over and the game starts (two What I did not checkI did not run plain AI-assisted; the runs are from my machine. |
|
@mrfelek thanks, your guess is right, and it's this PR's fault. #6237 fixes it at the source: LoadExec starts the shutdown the way exit does, so the thread parks until the process is replaced (the AGC entry points had the same gap, which is how #6237 found it on MGS4). I reproduced your stop with a test that pushes AudioOut2 audio across a LoadExec: on AI-assisted: yes (Claude Code). |
What
Fixes #5864.
libSceAudioOutregistered no shutdown callback, so a guest mixer thread kept callingsceAudioOut2ContextPushwhile exit ran the static destructors, and mixed from the freedg_portstable (SIGSEGV inAudioOut2MixPortsin the report).sceAudioOut2ContextAdvance,sceAudioOut2ContextPush,sceAudioOut2ContextDestroy,sceAudioOut2PortCreate,sceAudioOut2PortDestroy,sceAudioOut2PortGetState,sceAudioOut2PortSetAttributes,sceAudioOutOutputandsceAudioOutOutputs.LibcAwaitExit_nid_postfix, as the AGC entry points do since 5550ca6, instead of returning an error the title might retry.sceAudioOut2ContextAdvance(added in bb4ec48) also wakes on the shutdown token:grainReadybecomes acondition_variable_any. Without that, the callback would wait forever for a push whose advance is parked.The SDL devices are not closed at shutdown: the device callback reads only its heap-allocated context, which the exit does not free.
Relation to #5971: it gives the AudioOut2 port table process lifetime, and its debt entry records that the host does not stop the guest threads. This PR stops them. The two change different lines of
AudioOut2Port.cppand do not depend on each other.Tested
Ubuntu 26.04 under WSL2, GCC 15.2.0, Release,
SDL_AUDIODRIVER=dummy, on this branch rebased on73efd9407.audio_out_shutdown_tests(four ctest cases): a thread keeps pushing (AudioOut2) or outputting (AudioOut) while another thread requests exit; anatexithandler, which runs after the shutdown callbacks and before the library's static destructors, checks that the thread has stopped. A third case has a push waiting for an advance during exit and checks that the exit finishes; a fourth callssceAudioOut2ContextAdvanceafter the exit request and checks that it does not return.the mixer thread kept outputting audio after the audio shutdown,the exit did not finish,an advance after the exit request returned); with it they pass, 50 repetitions each.audio_out*tests pass; no compiler warnings;check_test_registration.pyandcheck_conventions.pypass.Not tested: Windows (no MinGW toolchain here), the full test suite (nothing else links
libSceAudioOut), a title run. The reporter of #5864 offered to run Hades II on this branch.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code