This commit is contained in:
Lars T Hansen 2015-05-13 10:35:42 +02:00
Родитель d149dbdc08
Коммит 81be93278f
2 изменённых файлов: 23 добавлений и 12 удалений

Просмотреть файл

@ -1032,7 +1032,13 @@ js::FutexRuntime::destroyInstance()
bool
js::FutexRuntime::isWaiting()
{
return state_ == Waiting || state_ == WaitingInterrupted;
// When a worker is awoken for an interrupt it goes into state
// WaitingNotifiedForInterrupt for a short time before it actually
// wakes up and goes into WaitingInterrupted. In those states the
// worker is still waiting, and if an explicit wake arrives the
// worker transitions to Woken. See further comments in
// FutexRuntime::wait().
return state_ == Waiting || state_ == WaitingInterrupted || state_ == WaitingNotifiedForInterrupt;
}
bool
@ -1102,7 +1108,7 @@ js::FutexRuntime::wait(JSContext* cx, double timeout_ms, AtomicsObject::FutexWai
*result = AtomicsObject::FutexOK;
goto finished;
case FutexRuntime::WokenForJSInterrupt:
case FutexRuntime::WaitingNotifiedForInterrupt:
// The interrupt handler may reenter the engine. In that case
// there are two complications:
//
@ -1112,7 +1118,7 @@ js::FutexRuntime::wait(JSContext* cx, double timeout_ms, AtomicsObject::FutexWai
// To that end, we flag the thread as interrupted around
// the interrupt and check state_ when the interrupt
// handler returns. A futexWake() call that reaches the
// runtime during the interrupt sets state_ to woken.
// runtime during the interrupt sets state_ to Woken.
//
// - It is in principle possible for futexWait() to be
// reentered on the same thread/runtime and waiting on the
@ -1160,7 +1166,7 @@ js::FutexRuntime::wake(WakeReason reason)
MOZ_ASSERT(lockHolder_ == PR_GetCurrentThread());
MOZ_ASSERT(isWaiting());
if (state_ == WaitingInterrupted && reason == WakeExplicit) {
if ((state_ == WaitingInterrupted || state_ == WaitingNotifiedForInterrupt) && reason == WakeExplicit) {
state_ = Woken;
return;
}
@ -1169,7 +1175,9 @@ js::FutexRuntime::wake(WakeReason reason)
state_ = Woken;
break;
case WakeForJSInterrupt:
state_ = WokenForJSInterrupt;
if (state_ == WaitingNotifiedForInterrupt)
return;
state_ = WaitingNotifiedForInterrupt;
break;
default:
MOZ_CRASH();

Просмотреть файл

@ -97,19 +97,22 @@ public:
//
// If the thread is waiting in a call to futexWait() and the
// reason is WakeForJSInterrupt then the futexWait() will return
// with WokenForJSInterrupt; in the latter case the caller of
// futexWait() must handle the interrupt.
// with WaitingNotifiedForInterrupt; in the latter case the caller
// of futexWait() must handle the interrupt.
void wake(WakeReason reason);
bool isWaiting();
private:
enum FutexState {
Idle, // We are not waiting or woken
Waiting, // We are waiting, nothing has happened yet
WaitingInterrupted, // We are waiting, but have been interrupted
Woken, // Woken by a script call to futexWake
WokenForJSInterrupt // Woken by an interrupt handler
Idle, // We are not waiting or woken
Waiting, // We are waiting, nothing has happened yet
WaitingNotifiedForInterrupt, // We are waiting, but have been interrupted,
// and have not yet started running the
// interrupt handler
WaitingInterrupted, // We are waiting, but have been interrupted
// and are running the interrupt handler
Woken // Woken by a script call to futexWake
};
// Condition variable that this runtime will wait on.