From 6ac7fbc5a4835a91bf51aa5828da2cd677eef890 Mon Sep 17 00:00:00 2001 From: boykopovar Date: Wed, 7 Oct 2026 18:41:41 +0300 Subject: [PATCH] fix(agc): stop profile writer before DLL teardown --- .../Execution/include/ProfileOutput.hpp | 8 +++++++- .../Execution/src/Driver/Lifecycle.cpp | 2 ++ .../prx/libSceAgcDriver/tests/ProfileOutput.cpp | 15 +++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/core/libs/prx/libSceAgcDriver/Execution/include/ProfileOutput.hpp b/core/libs/prx/libSceAgcDriver/Execution/include/ProfileOutput.hpp index 9c714409e..e64473e6c 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/include/ProfileOutput.hpp +++ b/core/libs/prx/libSceAgcDriver/Execution/include/ProfileOutput.hpp @@ -24,12 +24,17 @@ public: } ~ProfileOutput() { + Stop(); + } + + void Stop() { + std::lock_guard stopLock(stopMutex); { std::lock_guard lock(mutex); stopping = true; } changed.notify_one(); - worker.join(); + if (worker.joinable()) worker.join(); } bool Write(std::string text) { @@ -117,6 +122,7 @@ private: std::function writer; const std::size_t capacity; + std::mutex stopMutex; std::mutex mutex; std::condition_variable changed; std::condition_variable idle; diff --git a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Lifecycle.cpp b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Lifecycle.cpp index 5854c488a..8eae6d210 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Lifecycle.cpp +++ b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Lifecycle.cpp @@ -2,6 +2,7 @@ #include "prx/libSceAgcDriver/Execution/include/Driver/Diagnostics.hpp" #include "prx/libSceAgcDriver/Execution/include/GuestMemory.hpp" #include "prx/libSceAgcDriver/Execution/include/WorkerSampler.hpp" +#include "prx/libSceAgcDriver/Execution/include/ProfileOutput.hpp" #include "prx/libSceAgcDriver/Graphics/include/GuestBufferMemory.hpp" namespace AgcDriver::DriverDetail { @@ -44,6 +45,7 @@ void Driver::stop() { device.Reset(); replacedDevices.clear(); Graphics::ShutdownGuestBufferWorkers(); + ProfileOutput_nid_no_patch().Stop(); stopped = true; } diff --git a/core/libs/prx/libSceAgcDriver/tests/ProfileOutput.cpp b/core/libs/prx/libSceAgcDriver/tests/ProfileOutput.cpp index 5ac7e3ee0..72fb292b4 100644 --- a/core/libs/prx/libSceAgcDriver/tests/ProfileOutput.cpp +++ b/core/libs/prx/libSceAgcDriver/tests/ProfileOutput.cpp @@ -104,6 +104,20 @@ void WriterFailure() { } } +void ExplicitStop() { + std::string written; + AgcDriver::ProfileOutput output([&](std::string_view text) { written += text; }); + output.Write("pending output"); + output.Stop(); + output.Stop(); + output.Flush(); + Check(written == "pending output", "explicit stop did not drain pending output"); + bool failed = false; + try { output.Write("after stop"); } + catch (const std::runtime_error& error) { failed = std::string(error.what()) == "profile output is stopping"; } + Check(failed, "write after stop was accepted"); +} + } int main() { @@ -112,6 +126,7 @@ int main() { SlowWriter(); ConcurrentWriters(); WriterFailure(); + ExplicitStop(); std::cout << "profile output tests passed\n"; return 0; } catch (const std::exception& error) {