diff --git a/rpcs3/rpcs3.cpp b/rpcs3/rpcs3.cpp index 011dfbe39f..90d92cf1bd 100644 --- a/rpcs3/rpcs3.cpp +++ b/rpcs3/rpcs3.cpp @@ -656,7 +656,7 @@ int run_rpcs3(int argc, char** argv) // Initialize thread pool finalizer (on first use) static_cast(named_thread("", [](int) {})); - static std::unique_ptr log_file; + std::unique_ptr log_file; { // Check free space fs::device_stat stats{}; @@ -669,9 +669,17 @@ int run_rpcs3(int argc, char** argv) log_file = logs::make_file_listener(log_name, stats.avail_free / 4); } - static std::unique_ptr fatal_listener = std::make_unique(); + auto fatal_listener = std::make_unique(); logs::listener::add(fatal_listener.get()); + struct log_listener_shutdown_guard + { + ~log_listener_shutdown_guard() + { + logs::listener::shutdown_all(); + } + } log_listener_shutdown; + { // Write RPCS3 version logs::stored_message ver{sys_log.always()}; diff --git a/rpcs3/util/logs.cpp b/rpcs3/util/logs.cpp index f0afc95bac..3364e16ea9 100644 --- a/rpcs3/util/logs.cpp +++ b/rpcs3/util/logs.cpp @@ -372,6 +372,16 @@ void logs::listener::sync_all() } } +void logs::listener::shutdown_all() +{ + std::lock_guard lock(g_mutex); + + for (listener* lis = get_logger()->m_next.exchange(nullptr); lis;) + { + lis = lis->m_next.exchange(nullptr); + } +} + void logs::listener::close_all_prematurely() { for (listener* lis = get_logger(); lis; lis = lis->m_next) diff --git a/rpcs3/util/logs.hpp b/rpcs3/util/logs.hpp index 1b75bd6499..a2fcc863b2 100644 --- a/rpcs3/util/logs.hpp +++ b/rpcs3/util/logs.hpp @@ -98,6 +98,9 @@ namespace logs // Flush log to disk static void sync_all(); + // Detach all listeners before controlled shutdown tears them down. + static void shutdown_all(); + // Close file handle after flushing to disk (hazardous) static void close_all_prematurely(); };