Core: Fix ordering of thread state request processing

This commit is contained in:
Vicki Pfau 2020-11-19 23:27:52 -08:00
parent d20b2e1e23
commit bf611e01f2
1 changed files with 28 additions and 25 deletions

View File

@ -53,7 +53,13 @@ static void _waitOnInterrupt(struct mCoreThreadInternal* threadContext) {
}
}
void _waitPrologue(struct mCoreThreadInternal* threadContext, bool* videoFrameWait, bool* audioWait) {
static void _pokeRequest(struct mCoreThreadInternal* threadContext) {
if (threadContext->state == mTHREAD_RUNNING || threadContext->state == mTHREAD_PAUSED) {
threadContext->state = mTHREAD_REQUEST;
}
}
static void _waitPrologue(struct mCoreThreadInternal* threadContext, bool* videoFrameWait, bool* audioWait) {
MutexLock(&threadContext->sync.videoFrameMutex);
*videoFrameWait = threadContext->sync.videoFrameWait;
threadContext->sync.videoFrameWait = false;
@ -64,7 +70,7 @@ void _waitPrologue(struct mCoreThreadInternal* threadContext, bool* videoFrameWa
MutexUnlock(&threadContext->sync.audioBufferMutex);
}
void _waitEpilogue(struct mCoreThreadInternal* threadContext, bool videoFrameWait, bool audioWait) {
static void _waitEpilogue(struct mCoreThreadInternal* threadContext, bool videoFrameWait, bool audioWait) {
MutexLock(&threadContext->sync.audioBufferMutex);
threadContext->sync.audioWait = audioWait;
MutexUnlock(&threadContext->sync.audioBufferMutex);
@ -94,6 +100,7 @@ static void _waitOnRequest(struct mCoreThreadInternal* threadContext, enum mCore
bool videoFrameWait, audioWait;
_waitPrologue(threadContext, &videoFrameWait, &audioWait);
while (threadContext->requested & request) {
_pokeRequest(threadContext);
_wait(threadContext);
}
_waitEpilogue(threadContext, videoFrameWait, audioWait);
@ -110,16 +117,12 @@ static void _waitUntilNotState(struct mCoreThreadInternal* threadContext, enum m
static void _sendRequest(struct mCoreThreadInternal* threadContext, enum mCoreThreadRequest request) {
threadContext->requested |= request;
if (threadContext->state == mTHREAD_RUNNING) {
threadContext->state = mTHREAD_REQUEST;
}
_pokeRequest(threadContext);
}
static void _cancelRequest(struct mCoreThreadInternal* threadContext, enum mCoreThreadRequest request) {
threadContext->requested &= ~request;
if (threadContext->state == mTHREAD_RUNNING || threadContext->state == mTHREAD_PAUSED) {
threadContext->state = mTHREAD_REQUEST;
}
_pokeRequest(threadContext);
ConditionWake(&threadContext->stateCond);
}
@ -240,23 +243,6 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) {
}
MutexLock(&impl->stateMutex);
impl->requested &= ~pendingRequests | mTHREAD_REQ_PAUSE | mTHREAD_REQ_WAIT;
pendingRequests = impl->requested;
if (impl->state == mTHREAD_REQUEST) {
if (pendingRequests) {
if (pendingRequests & mTHREAD_REQ_PAUSE) {
impl->state = mTHREAD_PAUSED;
}
if (pendingRequests & mTHREAD_REQ_WAIT) {
impl->state = mTHREAD_PAUSED;
}
} else {
impl->state = mTHREAD_RUNNING;
ConditionWake(&threadContext->impl->stateCond);
}
}
while (impl->state >= mTHREAD_MIN_WAITING && impl->state < mTHREAD_EXITING) {
if (impl->state == mTHREAD_INTERRUPTING) {
impl->state = mTHREAD_INTERRUPTED;
@ -277,6 +263,23 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) {
break;
}
}
impl->requested &= ~pendingRequests | mTHREAD_REQ_PAUSE | mTHREAD_REQ_WAIT;
pendingRequests = impl->requested;
if (impl->state == mTHREAD_REQUEST) {
if (pendingRequests) {
if (pendingRequests & mTHREAD_REQ_PAUSE) {
impl->state = mTHREAD_PAUSED;
}
if (pendingRequests & mTHREAD_REQ_WAIT) {
impl->state = mTHREAD_PAUSED;
}
} else {
impl->state = mTHREAD_RUNNING;
ConditionWake(&threadContext->impl->stateCond);
}
}
MutexUnlock(&impl->stateMutex);
// Deferred callbacks can't be run inside of the critical section