From 848cf162af61955aafb177a8ac94f2e89cd8d256 Mon Sep 17 00:00:00 2001
From: Jeffrey Pfau <jeffrey@endrift.com>
Date: Tue, 17 Feb 2015 22:20:37 -0800
Subject: [PATCH] GBA Thread: Fix possible deadlock in video sync

---
 CHANGES                     | 1 +
 src/gba/supervisor/thread.c | 9 +++++++++
 2 files changed, 10 insertions(+)

diff --git a/CHANGES b/CHANGES
index 3ccb35883..11130830e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -37,6 +37,7 @@ Bugfixes:
  - Debugger: Disassembly now lists PSR bitmasks (fixes #191)
  - GBA BIOS: Prevent CpuSet and CpuFastSet from using BIOS addresses as a source (fixes #184)
  - GBA RR: Fix fallthrough error when reading tags from a movie
+ - GBA Thread: Fix possible deadlock in video sync
 Misc:
  - GBA Audio: Change internal audio sample buffer from 32-bit to 16-bit samples
  - GBA Memory: Simplify memory API and use fixed bus width
diff --git a/src/gba/supervisor/thread.c b/src/gba/supervisor/thread.c
index 93fb07439..14bb3a07c 100644
--- a/src/gba/supervisor/thread.c
+++ b/src/gba/supervisor/thread.c
@@ -60,6 +60,11 @@ static void _waitOnInterrupt(struct GBAThread* threadContext) {
 }
 
 static void _waitUntilNotState(struct GBAThread* threadContext, enum ThreadState oldState) {
+	MutexLock(&threadContext->sync.videoFrameMutex);
+	bool videoFrameWait = threadContext->sync.videoFrameWait;
+	threadContext->sync.videoFrameWait = false;
+	MutexUnlock(&threadContext->sync.videoFrameMutex);
+
 	while (threadContext->state == oldState) {
 		MutexUnlock(&threadContext->stateMutex);
 
@@ -74,6 +79,10 @@ static void _waitUntilNotState(struct GBAThread* threadContext, enum ThreadState
 		MutexLock(&threadContext->stateMutex);
 		ConditionWake(&threadContext->stateCond);
 	}
+
+	MutexLock(&threadContext->sync.videoFrameMutex);
+	threadContext->sync.videoFrameWait = videoFrameWait;
+	MutexUnlock(&threadContext->sync.videoFrameMutex);
 }
 
 static void _pauseThread(struct GBAThread* threadContext, bool onThread) {