From 90c49befd4e918d5a5f7638c23f836844ae065b1 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 12 Oct 2013 02:08:00 -0700 Subject: [PATCH] Fix a possible race on shutdown. --- Core/MIPS/MIPSDebugInterface.cpp | 2 +- Core/System.cpp | 21 +++++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Core/MIPS/MIPSDebugInterface.cpp b/Core/MIPS/MIPSDebugInterface.cpp index ea55ab2ced..d8e5962e35 100644 --- a/Core/MIPS/MIPSDebugInterface.cpp +++ b/Core/MIPS/MIPSDebugInterface.cpp @@ -126,7 +126,7 @@ unsigned int MIPSDebugInterface::readMemory(unsigned int address) bool MIPSDebugInterface::isAlive() { - return PSP_IsInited(); + return PSP_IsInited() && coreState != CORE_ERROR && coreState != CORE_POWERDOWN; } bool MIPSDebugInterface::isBreakpoint(unsigned int address) diff --git a/Core/System.cpp b/Core/System.cpp index ca39a6b6a1..125114ecef 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -67,6 +67,7 @@ static PSPMixer *mixer; static std::thread *cpuThread = NULL; static recursive_mutex cpuThreadLock; static condition_variable cpuThreadCond; +static condition_variable cpuThreadReplyCond; static u64 cpuThreadUntil; // This can be read and written from ANYWHERE. @@ -95,9 +96,11 @@ bool IsOnSeparateCPUThread() { } bool CPU_NextState(CPUThreadState from, CPUThreadState to) { + lock_guard guard(cpuThreadLock); if (cpuThreadState == from) { cpuThreadState = to; cpuThreadCond.notify_one(); + cpuThreadReplyCond.notify_one(); return true; } else { return false; @@ -105,8 +108,10 @@ bool CPU_NextState(CPUThreadState from, CPUThreadState to) { } void CPU_SetState(CPUThreadState to) { + lock_guard guard(cpuThreadLock); cpuThreadState = to; cpuThreadCond.notify_one(); + cpuThreadReplyCond.notify_one(); } bool CPU_IsReady() { @@ -121,11 +126,11 @@ bool CPU_HasPendingAction() { return cpuThreadState != CPU_THREAD_RUNNING; } -void CPU_WaitStatus(bool (*pred)()) { - cpuThreadLock.lock(); - while (!pred()) - cpuThreadCond.wait(cpuThreadLock); - cpuThreadLock.unlock(); +void CPU_WaitStatus(condition_variable &cond, bool (*pred)()) { + lock_guard guard(cpuThreadLock); + while (!pred()) { + cond.wait(cpuThreadLock); + } } void CPU_Shutdown(); @@ -219,7 +224,7 @@ void CPU_RunLoop() { while (cpuThreadState != CPU_THREAD_SHUTDOWN) { - CPU_WaitStatus(&CPU_HasPendingAction); + CPU_WaitStatus(cpuThreadCond, &CPU_HasPendingAction); switch (cpuThreadState) { case CPU_THREAD_EXECUTE: mipsr4k.RunLoopUntil(cpuThreadUntil); @@ -271,7 +276,7 @@ bool PSP_Init(const CoreParameter &coreParam, std::string *error_string) { Core_ListenShutdown(System_Wake); CPU_SetState(CPU_THREAD_PENDING); cpuThread = new std::thread(&CPU_RunLoop); - CPU_WaitStatus(&CPU_IsReady); + CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsReady); } else { CPU_Init(); } @@ -298,7 +303,7 @@ void PSP_Shutdown() { Core_NotifyShutdown(); if (cpuThread != NULL) { CPU_SetState(CPU_THREAD_SHUTDOWN); - CPU_WaitStatus(&CPU_IsShutdown); + CPU_WaitStatus(cpuThreadReplyCond, &CPU_IsShutdown); delete cpuThread; cpuThread = 0; } else {