GE Debugger: Prevent hang on shutdown.

Since we're blocking the Emu thread, we can't use a hook from the Emu
thread to wake up.

The change to lifecycle callbacks caused this.
This commit is contained in:
Unknown W. Brackets 2018-06-11 14:54:42 -07:00
parent 6c494c3849
commit 0ed2c03350
5 changed files with 23 additions and 12 deletions

View File

@ -54,7 +54,8 @@ static std::condition_variable m_InactiveCond;
static std::mutex m_hInactiveMutex;
static bool singleStepPending = false;
static int steppingCounter = 0;
static std::set<CoreLifecycleFunc> shutdownFuncs;
static std::set<CoreLifecycleFunc> lifecycleFuncs;
static std::set<CoreStopRequestFunc> stopFuncs;
static bool windowHidden = false;
static double lastActivity = 0.0;
static double lastKeepAwake = 0.0;
@ -76,17 +77,24 @@ void Core_NotifyActivity() {
}
void Core_ListenLifecycle(CoreLifecycleFunc func) {
shutdownFuncs.insert(func);
lifecycleFuncs.insert(func);
}
void Core_NotifyLifecycle(CoreLifecycle stage) {
for (auto it = shutdownFuncs.begin(); it != shutdownFuncs.end(); ++it) {
(*it)(stage);
for (auto func : lifecycleFuncs) {
func(stage);
}
}
void Core_ListenStopRequest(CoreStopRequestFunc func) {
stopFuncs.insert(func);
}
void Core_Stop() {
Core_UpdateState(CORE_POWERDOWN);
for (auto func : stopFuncs) {
func();
}
}
bool Core_IsStepping() {

View File

@ -51,10 +51,15 @@ enum class CoreLifecycle {
MEMORY_REINITED,
};
// Callback is called on the Emu thread.
typedef void (* CoreLifecycleFunc)(CoreLifecycle stage);
void Core_ListenLifecycle(CoreLifecycleFunc func);
void Core_NotifyLifecycle(CoreLifecycle stage);
// Callback is executed on requesting thread.
typedef void (* CoreStopRequestFunc)();
void Core_ListenStopRequest(CoreStopRequestFunc callback);
bool Core_IsStepping();
bool Core_IsActive();

View File

@ -197,12 +197,10 @@ void ResumeFromStepping() {
SetPauseAction(PAUSE_CONTINUE, false);
}
void ForceUnpause(CoreLifecycle stage) {
if (stage == CoreLifecycle::STOPPING) {
SetPauseAction(PAUSE_CONTINUE, false);
actionComplete = true;
actionWait.notify_all();
}
void ForceUnpause() {
SetPauseAction(PAUSE_CONTINUE, false);
actionComplete = true;
actionWait.notify_all();
}
} // namespace

View File

@ -38,5 +38,5 @@ namespace GPUStepping {
bool GPU_SetCmdValue(u32 op);
void ResumeFromStepping();
void ForceUnpause(CoreLifecycle stage);
void ForceUnpause();
};

View File

@ -67,7 +67,7 @@ void CGEDebugger::Init() {
CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent)
: Dialog((LPCSTR)IDD_GEDEBUGGER, _hInstance, _hParent) {
GPUBreakpoints::Init();
Core_ListenLifecycle(ForceUnpause);
Core_ListenStopRequest(ForceUnpause);
// minimum size = a little more than the default
RECT windowRect;