зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1139856
- do not lose wakeups. r=luke
This commit is contained in:
Родитель
d149dbdc08
Коммит
81be93278f
|
@ -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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче