all repos — mgba @ f008c68761ceb297469f1aae6e174db19498b822

mGBA Game Boy Advance Emulator

GBA Thread: Make GBAThreadInterrupt thread-safe
Jeffrey Pfau jeffrey@endrift.com
Sat, 08 Nov 2014 04:28:16 -0800
commit

f008c68761ceb297469f1aae6e174db19498b822

parent

190ea7164666202ebae534511e5890b2238141b6

2 files changed, 15 insertions(+), 4 deletions(-)

jump to
M src/gba/gba-thread.csrc/gba/gba-thread.c

@@ -313,6 +313,8 @@ ConditionInit(&threadContext->sync.videoFrameRequiredCond);

MutexInit(&threadContext->sync.audioBufferMutex); ConditionInit(&threadContext->sync.audioRequiredCond); + threadContext->interruptDepth = 0; + #ifndef _WIN32 sigset_t signals; sigemptyset(&signals);

@@ -426,10 +428,12 @@ }

void GBAThreadInterrupt(struct GBAThread* threadContext) { MutexLock(&threadContext->stateMutex); - threadContext->savedState = threadContext->state; - if (threadContext->sync.audioWait) { - ConditionWake(&threadContext->sync.audioRequiredCond); + ++threadContext->interruptDepth; + if (threadContext->interruptDepth > 1) { + MutexUnlock(&threadContext->stateMutex); + return; } + threadContext->savedState = threadContext->state; _waitOnInterrupt(threadContext); threadContext->state = THREAD_INTERRUPTING; if (threadContext->debugger && threadContext->debugger->state == DEBUGGER_RUNNING) {

@@ -441,7 +445,13 @@ MutexUnlock(&threadContext->stateMutex);

} void GBAThreadContinue(struct GBAThread* threadContext) { - _changeState(threadContext, threadContext->savedState, 1); + MutexLock(&threadContext->stateMutex); + --threadContext->interruptDepth; + if (threadContext->interruptDepth < 1) { + threadContext->state = threadContext->savedState; + ConditionWake(&threadContext->stateCond); + } + MutexUnlock(&threadContext->stateMutex); } void GBAThreadPause(struct GBAThread* threadContext) {
M src/gba/gba-thread.hsrc/gba/gba-thread.h

@@ -76,6 +76,7 @@

Mutex stateMutex; Condition stateCond; enum ThreadState savedState; + int interruptDepth; LogHandler logHandler; int logLevel;