mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-23 09:03:22 -05:00
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 (#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.
35 lines
768 B
C++
35 lines
768 B
C++
#include <atomic>
|
|
#include <cstdint>
|
|
#include "prx/libc/include/Shutdown.hpp"
|
|
#include "AudioOutShutdown.hpp"
|
|
|
|
namespace {
|
|
|
|
std::atomic<std::uint32_t> inside{0};
|
|
std::atomic<bool> stopping{false};
|
|
|
|
void Leave() {
|
|
if (inside.fetch_sub(1) == 1) inside.notify_all();
|
|
}
|
|
|
|
void Stop() {
|
|
stopping.store(true);
|
|
for (auto count = inside.load(); count != 0; count = inside.load()) inside.wait(count);
|
|
}
|
|
|
|
}
|
|
|
|
AudioOutCall::AudioOutCall() {
|
|
static const bool registered = (LibcRegisterShutdown_nid_postfix(Stop), true);
|
|
static_cast<void>(registered);
|
|
inside.fetch_add(1);
|
|
if (stopping.load() || LibcShutdownToken_nid_postfix().stop_requested()) {
|
|
Leave();
|
|
throw ProcessShutdown{};
|
|
}
|
|
}
|
|
|
|
AudioOutCall::~AudioOutCall() {
|
|
Leave();
|
|
}
|