all repos — mgba @ 8e4a3439c05395f0c274db4d9089f75867cd71f4

mGBA Game Boy Advance Emulator

Fix threading issues with the video thread and the main thread deadlocking
Jeffrey Pfau jeffrey@endrift.com
Sat, 18 Oct 2014 02:26:32 -0700
commit

8e4a3439c05395f0c274db4d9089f75867cd71f4

parent

f1de3d603a96cb8a5f8e5bad2f0e251779d93f0e

3 files changed, 10 insertions(+), 1 deletions(-)

jump to
M src/platform/qt/Display.cppsrc/platform/qt/Display.cpp

@@ -42,6 +42,7 @@ m_painter = new Painter(this);

m_painter->setContext(thread); m_painter->setBacking(buffer); m_painter->moveToThread(m_drawThread); + m_context = thread; doneCurrent(); context()->moveToThread(m_drawThread); connect(m_drawThread, SIGNAL(started()), m_painter, SLOT(start()));

@@ -50,9 +51,13 @@ }

void Display::stopDrawing() { if (m_drawThread) { + GBAThreadInterrupt(m_context); + GBASyncSuspendDrawing(&m_context->sync); QMetaObject::invokeMethod(m_painter, "stop", Qt::BlockingQueuedConnection); m_drawThread->exit(); m_drawThread = nullptr; + GBASyncResumeDrawing(&m_context->sync); + GBAThreadContinue(m_context); } }

@@ -70,7 +75,11 @@ }

void Display::resizeEvent(QResizeEvent* event) { if (m_drawThread) { + GBAThreadInterrupt(m_context); + GBASyncSuspendDrawing(&m_context->sync); QMetaObject::invokeMethod(m_painter, "resize", Qt::BlockingQueuedConnection, Q_ARG(QSize, event->size())); + GBASyncResumeDrawing(&m_context->sync); + GBAThreadContinue(m_context); } }
M src/platform/qt/Display.hsrc/platform/qt/Display.h

@@ -29,6 +29,7 @@

private: Painter* m_painter; QThread* m_drawThread; + GBAThread* m_context; }; class Painter : public QObject {
M src/platform/qt/GameController.cppsrc/platform/qt/GameController.cpp

@@ -215,7 +215,6 @@

void GameController::loadState(int slot) { GBAThreadInterrupt(&m_threadContext); GBALoadState(m_threadContext.gba, m_threadContext.stateDir, slot); - ConditionWake(&m_threadContext.sync.videoFrameAvailableCond); // Hack: wake up the drawing thread GBAThreadContinue(&m_threadContext); emit stateLoaded(&m_threadContext); emit frameAvailable(m_drawContext);