GBA Thread: Make GBAThreadInterrupt thread-safe
Jeffrey Pfau jeffrey@endrift.com
Sat, 08 Nov 2014 04:28:16 -0800
2 files changed,
15 insertions(+),
4 deletions(-)
M
src/gba/gba-thread.c
→
src/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.h
→
src/gba/gba-thread.h
@@ -76,6 +76,7 @@
Mutex stateMutex; Condition stateCond; enum ThreadState savedState; + int interruptDepth; LogHandler logHandler; int logLevel;