From 6320dd553915704d2c00ec280c0aa1029797161c Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sat, 29 Jan 2022 17:16:01 -0600 Subject: [PATCH] fix shutdown process crashed on shutdown and reboots --- src/common/Timer.cpp | 26 ++++++++++++++++++++++++++ src/common/Timer.h | 1 + src/core/kernel/init/CxbxKrnl.cpp | 17 +++++++++++------ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/common/Timer.cpp b/src/common/Timer.cpp index 457b3867f..947cd471e 100644 --- a/src/common/Timer.cpp +++ b/src/common/Timer.cpp @@ -122,6 +122,32 @@ void Timer_Destroy(TimerObject* Timer) TimerList.erase(TimerList.begin() + index); } +void Timer_Shutdown() +{ + unsigned int index, i; + TimerMtx.lock(); + + index = TimerList.size(); + for (i = 0; i < index; i++) { + TimerObject* Timer = TimerList[i]; + Timer_Exit(Timer); + } + + int counter = 0; + while (TimerList.size()) { + if (counter >= 8) { + break; + } + TimerMtx.unlock(); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + TimerMtx.lock(); + counter++; + + } + TimerList.clear(); + TimerMtx.unlock(); +} + // Thread that runs the timer void ClockThread(TimerObject* Timer) { diff --git a/src/common/Timer.h b/src/common/Timer.h index b99bb93d9..007c75536 100644 --- a/src/common/Timer.h +++ b/src/common/Timer.h @@ -63,6 +63,7 @@ void Timer_Exit(TimerObject* Timer); void Timer_ChangeExpireTime(TimerObject* Timer, uint64_t Expire_ms); uint64_t GetTime_NS(TimerObject* Timer); void Timer_Init(); +void Timer_Shutdown(); int64_t Timer_GetScaledPerformanceCounter(int64_t Period); diff --git a/src/core/kernel/init/CxbxKrnl.cpp b/src/core/kernel/init/CxbxKrnl.cpp index c6a74603d..0e863c303 100644 --- a/src/core/kernel/init/CxbxKrnl.cpp +++ b/src/core/kernel/init/CxbxKrnl.cpp @@ -1628,9 +1628,6 @@ void CxbxKrnlShutDown(bool is_reboot) g_EmuShared->SetBootFlags(&BootFlags); } - // This is very important process to prevent false positive report and allow IDEs to continue debug multiple reboots. - CxbxrKrnlSuspendThreads(); - // NOTE: This causes a hang when exiting while NV2A is processing // This is okay for now: It won't leak memory or resources since TerminateProcess will free everything // delete g_NV2A; // TODO : g_pXbox @@ -1643,15 +1640,23 @@ void CxbxKrnlShutDown(bool is_reboot) g_io_mu_metadata = nullptr; } - // Shutdown the memory manager - g_VMManager.Shutdown(); - // Shutdown the render manager if (g_renderbase != nullptr) { g_renderbase->Shutdown(); g_renderbase = nullptr; } + // This is very important process to prevent false positive report and allow IDEs to continue debug multiple reboots. + CxbxrKrnlSuspendThreads(); + + // NOTE: Require to be after g_renderbase's shutdown process. + // Next thing we need to do is shutdown our timer threads. + Timer_Shutdown(); + + // NOTE: Must be last step of shutdown process and before CxbxUnlockFilePath call! + // Shutdown the memory manager + g_VMManager.Shutdown(); + CxbxUnlockFilePath(); if (CxbxKrnl_hEmuParent != NULL && !is_reboot) {