[DOM] worker cleanup.

This commit is contained in:
Moonchild 2022-02-09 23:34:40 +00:00 • committed by roytam1
commit a94d85142d

View file

@ -4646,9 +4646,14 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
AssertIsOnWorkerThread(); AssertIsOnWorkerThread();
MOZ_ASSERT(mThread); MOZ_ASSERT(mThread);
RefPtr<WorkerThread> thread;
{ {
MutexAutoLock lock(mMutex); MutexAutoLock lock(mMutex);
mJSContext = aCx; mJSContext = aCx;
// mThread is set before we enter, and is never changed during DoRunLoop.
// copy to local so we don't trigger mutex analysis
MOZ_ASSERT(mThread);
thread = mThread;
MOZ_ASSERT(mStatus == Pending); MOZ_ASSERT(mStatus == Pending);
mStatus = Running; mStatus = Running;
@ -4678,7 +4683,7 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
while (mControlQueue.IsEmpty() && while (mControlQueue.IsEmpty() &&
!(debuggerRunnablesPending = !mDebuggerQueue.IsEmpty()) && !(debuggerRunnablesPending = !mDebuggerQueue.IsEmpty()) &&
!(normalRunnablesPending = NS_HasPendingEvents(mThread))) { !(normalRunnablesPending = NS_HasPendingEvents(thread))) {
WaitForWorkerEvents(); WaitForWorkerEvents();
} }
@ -4688,7 +4693,7 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
// irrelevant // irrelevant
// The state of the world may have changed, recheck it. // The state of the world may have changed, recheck it.
normalRunnablesPending = NS_HasPendingEvents(mThread); normalRunnablesPending = NS_HasPendingEvents(thread);
// The debugger queue doesn't get cleared, so we can ignore that. // The debugger queue doesn't get cleared, so we can ignore that.
} }
@ -4781,9 +4786,9 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
} }
} else if (normalRunnablesPending) { } else if (normalRunnablesPending) {
// Process a single runnable from the main queue. // Process a single runnable from the main queue.
NS_ProcessNextEvent(mThread, false); NS_ProcessNextEvent(thread, false);
normalRunnablesPending = NS_HasPendingEvents(mThread); normalRunnablesPending = NS_HasPendingEvents(thread);
if (normalRunnablesPending && GlobalScope()) { if (normalRunnablesPending && GlobalScope()) {
// Now *might* be a good time to GC. Let the JS engine make the decision. // Now *might* be a good time to GC. Let the JS engine make the decision.
JSAutoCompartment ac(aCx, GlobalScope()->GetGlobalJSObject()); JSAutoCompartment ac(aCx, GlobalScope()->GetGlobalJSObject());
@ -5185,10 +5190,14 @@ WorkerPrivate::ClearMainEventQueue(WorkerRanOrNot aRanOrNot)
mCancelAllPendingRunnables = true; mCancelAllPendingRunnables = true;
if (WorkerNeverRan == aRanOrNot) { if (WorkerNeverRan == aRanOrNot) {
for (uint32_t count = mPreStartRunnables.Length(), index = 0; nsTArray<RefPtr<WorkerRunnable>> prestart;
index < count; {
MutexAutoLock lock(mMutex);
mPreStartRunnables.SwapElements(prestart);
}
for (uint32_t count = prestart.Length(), index = 0; index < count;
index++) { index++) {
RefPtr<WorkerRunnable> runnable = mPreStartRunnables[index].forget(); RefPtr<WorkerRunnable> runnable = prestart[index].forget();
static_cast<nsIRunnable*>(runnable.get())->Run(); static_cast<nsIRunnable*>(runnable.get())->Run();
} }
} else { } else {
@ -5434,20 +5443,20 @@ WorkerPrivate::CreateNewSyncLoop(Status aFailStatus)
{ {
AssertIsOnWorkerThread(); AssertIsOnWorkerThread();
nsCOMPtr<nsIEventTarget> realEventTarget;
{ {
MutexAutoLock lock(mMutex); MutexAutoLock lock(mMutex);
if (mStatus >= aFailStatus) { if (mStatus >= aFailStatus) {
return nullptr; return nullptr;
} }
nsCOMPtr<nsIThreadInternal> thread = do_QueryInterface(NS_GetCurrentThread());
MOZ_ASSERT(thread);
MOZ_ALWAYS_SUCCEEDS(thread->PushEventQueue(getter_AddRefs(realEventTarget)));
} }
nsCOMPtr<nsIThreadInternal> thread = do_QueryInterface(NS_GetCurrentThread());
MOZ_ASSERT(thread);
nsCOMPtr<nsIEventTarget> realEventTarget;
MOZ_ALWAYS_SUCCEEDS(thread->PushEventQueue(getter_AddRefs(realEventTarget)));
RefPtr<EventTarget> workerEventTarget = RefPtr<EventTarget> workerEventTarget =
new EventTarget(this, realEventTarget); new EventTarget(this, realEventTarget);
@ -5469,9 +5478,18 @@ WorkerPrivate::RunCurrentSyncLoop()
{ {
AssertIsOnWorkerThread(); AssertIsOnWorkerThread();
RefPtr<WorkerThread> thread;
JSContext* cx = GetJSContext(); JSContext* cx = GetJSContext();
MOZ_ASSERT(cx); MOZ_ASSERT(cx);
// mThread is set before we enter, and is never changed during
// RunCurrentSyncLoop.
{
MutexAutoLock lock(mMutex);
// Copy to local
thread = mThread;
}
// This should not change between now and the time we finish running this sync // This should not change between now and the time we finish running this sync
// loop. // loop.
uint32_t currentLoopIndex = mSyncLoopStack.Length() - 1; uint32_t currentLoopIndex = mSyncLoopStack.Length() - 1;
@ -5490,7 +5508,7 @@ WorkerPrivate::RunCurrentSyncLoop()
bool normalRunnablesPending = false; bool normalRunnablesPending = false;
// Don't block with the periodic GC timer running. // Don't block with the periodic GC timer running.
if (!NS_HasPendingEvents(mThread)) { if (!NS_HasPendingEvents(thread)) {
SetGCTimerMode(IdleTimer); SetGCTimerMode(IdleTimer);
} }
@ -5501,7 +5519,7 @@ WorkerPrivate::RunCurrentSyncLoop()
for (;;) { for (;;) {
while (mControlQueue.IsEmpty() && while (mControlQueue.IsEmpty() &&
!normalRunnablesPending && !normalRunnablesPending &&
!(normalRunnablesPending = NS_HasPendingEvents(mThread))) { !(normalRunnablesPending = NS_HasPendingEvents(thread))) {
WaitForWorkerEvents(); WaitForWorkerEvents();
} }
@ -5510,7 +5528,7 @@ WorkerPrivate::RunCurrentSyncLoop()
// XXXkhuey how should we handle Abort here? See Bug 1003730. // XXXkhuey how should we handle Abort here? See Bug 1003730.
// The state of the world may have changed. Recheck it. // The state of the world may have changed. Recheck it.
normalRunnablesPending = NS_HasPendingEvents(mThread); normalRunnablesPending = NS_HasPendingEvents(thread);
// NB: If we processed a NotifyRunnable, we might have run // NB: If we processed a NotifyRunnable, we might have run
// non-control runnables, one of which may have shut down the // non-control runnables, one of which may have shut down the
@ -5533,7 +5551,7 @@ WorkerPrivate::RunCurrentSyncLoop()
// Make sure the periodic timer is running before we continue. // Make sure the periodic timer is running before we continue.
SetGCTimerMode(PeriodicTimer); SetGCTimerMode(PeriodicTimer);
MOZ_ALWAYS_TRUE(NS_ProcessNextEvent(mThread, false)); MOZ_ALWAYS_TRUE(NS_ProcessNextEvent(thread, false));
// Now *might* be a good time to GC. Let the JS engine make the decision. // Now *might* be a good time to GC. Let the JS engine make the decision.
if (JS::CurrentGlobalOrNull(cx)) { if (JS::CurrentGlobalOrNull(cx)) {
@ -5542,7 +5560,7 @@ WorkerPrivate::RunCurrentSyncLoop()
} }
} }
// Make sure that the stack didn't change underneath us. // Make sure that the stack didn't change under us.
MOZ_ASSERT(mSyncLoopStack[currentLoopIndex] == loopInfo); MOZ_ASSERT(mSyncLoopStack[currentLoopIndex] == loopInfo);
return DestroySyncLoop(currentLoopIndex); return DestroySyncLoop(currentLoopIndex);