From f05a385d6afd6df4b7f846563c550b6f0e51e705 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Thu, 8 Jan 2015 20:04:44 -0800 Subject: [PATCH] GBA Thread: Add a crashed state to the thread --- src/gba/gba-thread.c | 18 +++++++++++++++++- src/gba/gba-thread.h | 5 ++++- src/gba/gba.c | 16 ++++++++++++---- src/platform/qt/GameController.cpp | 3 --- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/gba/gba-thread.c b/src/gba/gba-thread.c index 66d30e63c..ce0814acd 100644 --- a/src/gba/gba-thread.c +++ b/src/gba/gba-thread.c @@ -212,7 +212,7 @@ static THREAD_ENTRY _GBAThreadRun(void* context) { } } - while (threadContext->state != THREAD_SHUTDOWN) { + while (threadContext->state < THREAD_SHUTDOWN) { _changeState(threadContext, THREAD_SHUTDOWN, false); } @@ -356,6 +356,22 @@ bool GBAThreadHasStarted(struct GBAThread* threadContext) { return hasStarted; } +bool GBAThreadHasExited(struct GBAThread* threadContext) { + bool hasExited; + MutexLock(&threadContext->stateMutex); + hasExited = threadContext->state > THREAD_EXITING; + MutexUnlock(&threadContext->stateMutex); + return hasExited; +} + +bool GBAThreadHasCrashed(struct GBAThread* threadContext) { + bool hasExited; + MutexLock(&threadContext->stateMutex); + hasExited = threadContext->state == THREAD_CRASHED; + MutexUnlock(&threadContext->stateMutex); + return hasExited; +} + void GBAThreadEnd(struct GBAThread* threadContext) { MutexLock(&threadContext->stateMutex); if (threadContext->debugger && threadContext->debugger->state == DEBUGGER_RUNNING) { diff --git a/src/gba/gba-thread.h b/src/gba/gba-thread.h index 5039d3941..4a923ec75 100644 --- a/src/gba/gba-thread.h +++ b/src/gba/gba-thread.h @@ -28,7 +28,8 @@ enum ThreadState { THREAD_PAUSING, THREAD_RESETING, THREAD_EXITING, - THREAD_SHUTDOWN + THREAD_SHUTDOWN, + THREAD_CRASHED }; struct GBASync { @@ -107,6 +108,8 @@ void GBAMapArgumentsToContext(const struct GBAArguments*, struct GBAThread*); bool GBAThreadStart(struct GBAThread* threadContext); bool GBAThreadHasStarted(struct GBAThread* threadContext); +bool GBAThreadHasExited(struct GBAThread* threadContext); +bool GBAThreadHasCrashed(struct GBAThread* threadContext); void GBAThreadEnd(struct GBAThread* threadContext); void GBAThreadReset(struct GBAThread* threadContext); void GBAThreadJoin(struct GBAThread* threadContext); diff --git a/src/gba/gba.c b/src/gba/gba.c index 8136f78e8..111276452 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -619,15 +619,23 @@ static void _GBAVLog(struct GBA* gba, enum GBALogLevel level, const char* format return; } - if (threadContext && threadContext->logHandler) { - threadContext->logHandler(threadContext, level, format, args); - return; + gba->cpu->nextEvent = 0; + if (threadContext) { + if (level == GBA_LOG_FATAL) { + MutexLock(&threadContext->stateMutex); + threadContext->state = THREAD_CRASHED; + MutexUnlock(&threadContext->stateMutex); + } + if (threadContext->logHandler) { + threadContext->logHandler(threadContext, level, format, args); + return; + } } vprintf(format, args); printf("\n"); - if (level == GBA_LOG_FATAL) { + if (level == GBA_LOG_FATAL && !threadContext) { abort(); } } diff --git a/src/platform/qt/GameController.cpp b/src/platform/qt/GameController.cpp index b5b2792f6..aba44c67b 100644 --- a/src/platform/qt/GameController.cpp +++ b/src/platform/qt/GameController.cpp @@ -109,9 +109,6 @@ GameController::GameController(QObject* parent) m_threadContext.logHandler = [] (GBAThread* context, enum GBALogLevel level, const char* format, va_list args) { GameController* controller = static_cast(context->userData); if (level == GBA_LOG_FATAL) { - MutexLock(&controller->m_threadContext.stateMutex); - controller->m_threadContext.state = THREAD_EXITING; - MutexUnlock(&controller->m_threadContext.stateMutex); QMetaObject::invokeMethod(controller, "crashGame", Q_ARG(const QString&, QString().vsprintf(format, args))); } else if (!(controller->m_logLevels & level)) { return;