mirror of https://github.com/mgba-emu/mgba.git
GBA Thread: Make GBAThreadInterrupt and -Continue check for the thread status, resolving several deadlocks
This commit is contained in:
parent
6e62ba8bb2
commit
d83520c5a2
|
@ -426,10 +426,14 @@ void GBAThreadJoin(struct GBAThread* threadContext) {
|
|||
}
|
||||
}
|
||||
|
||||
bool GBAThreadIsActive(struct GBAThread* threadContext) {
|
||||
return threadContext->state >= THREAD_RUNNING && threadContext->state < THREAD_EXITING;
|
||||
}
|
||||
|
||||
void GBAThreadInterrupt(struct GBAThread* threadContext) {
|
||||
MutexLock(&threadContext->stateMutex);
|
||||
++threadContext->interruptDepth;
|
||||
if (threadContext->interruptDepth > 1) {
|
||||
if (threadContext->interruptDepth > 1 || !GBAThreadIsActive(threadContext)) {
|
||||
MutexUnlock(&threadContext->stateMutex);
|
||||
return;
|
||||
}
|
||||
|
@ -447,7 +451,7 @@ void GBAThreadInterrupt(struct GBAThread* threadContext) {
|
|||
void GBAThreadContinue(struct GBAThread* threadContext) {
|
||||
MutexLock(&threadContext->stateMutex);
|
||||
--threadContext->interruptDepth;
|
||||
if (threadContext->interruptDepth < 1) {
|
||||
if (threadContext->interruptDepth < 1 && GBAThreadIsActive(threadContext)) {
|
||||
threadContext->state = threadContext->savedState;
|
||||
ConditionWake(&threadContext->stateCond);
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ void GBAThreadEnd(struct GBAThread* threadContext);
|
|||
void GBAThreadReset(struct GBAThread* threadContext);
|
||||
void GBAThreadJoin(struct GBAThread* threadContext);
|
||||
|
||||
bool GBAThreadIsActive(struct GBAThread* threadContext);
|
||||
void GBAThreadInterrupt(struct GBAThread* threadContext);
|
||||
void GBAThreadContinue(struct GBAThread* threadContext);
|
||||
|
||||
|
|
|
@ -52,14 +52,18 @@ void Display::startDrawing(const uint32_t* buffer, GBAThread* thread) {
|
|||
|
||||
void Display::stopDrawing() {
|
||||
if (m_drawThread) {
|
||||
if (GBAThreadIsActive(m_context)) {
|
||||
GBAThreadInterrupt(m_context);
|
||||
GBASyncSuspendDrawing(&m_context->sync);
|
||||
}
|
||||
QMetaObject::invokeMethod(m_painter, "stop", Qt::BlockingQueuedConnection);
|
||||
m_drawThread->exit();
|
||||
m_drawThread = nullptr;
|
||||
if (GBAThreadIsActive(m_context)) {
|
||||
GBASyncResumeDrawing(&m_context->sync);
|
||||
GBAThreadContinue(m_context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Display::forceDraw() {
|
||||
|
|
|
@ -250,13 +250,9 @@ void GameController::setAudioBufferSamples(int samples) {
|
|||
}
|
||||
|
||||
void GameController::setFPSTarget(float fps) {
|
||||
if (m_gameOpen) {
|
||||
GBAThreadInterrupt(&m_threadContext);
|
||||
m_threadContext.fpsTarget = fps;
|
||||
GBAThreadContinue(&m_threadContext);
|
||||
} else {
|
||||
m_threadContext.fpsTarget = fps;
|
||||
}
|
||||
QMetaObject::invokeMethod(m_audioProcessor, "inputParametersChanged");
|
||||
}
|
||||
|
||||
|
@ -315,23 +311,15 @@ void GameController::setTurbo(bool set, bool forced) {
|
|||
}
|
||||
|
||||
void GameController::setAVStream(GBAAVStream* stream) {
|
||||
if (m_gameOpen) {
|
||||
GBAThreadInterrupt(&m_threadContext);
|
||||
m_threadContext.stream = stream;
|
||||
GBAThreadContinue(&m_threadContext);
|
||||
} else {
|
||||
m_threadContext.stream = stream;
|
||||
}
|
||||
}
|
||||
|
||||
void GameController::clearAVStream() {
|
||||
if (m_gameOpen) {
|
||||
GBAThreadInterrupt(&m_threadContext);
|
||||
m_threadContext.stream = nullptr;
|
||||
GBAThreadContinue(&m_threadContext);
|
||||
} else {
|
||||
m_threadContext.stream = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void GameController::updateKeys() {
|
||||
|
|
Loading…
Reference in New Issue