import from UXP: Issue #2452 - Handle re-entrant Microtask checkpoints from Events dispatched by StableState callbacks (a2c28b42)

This commit is contained in:
2024-01-18 11:52:16 +08:00
parent 7f577e2b3a
commit 0ce6cceb19
2 changed files with 27 additions and 4 deletions
+23 -1
View File
@@ -1506,7 +1506,29 @@ CycleCollectedJSContext::AfterProcessMicrotasks()
}
// Cleanup Indexed Database transactions:
// https://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint
CleanupIDBTransactions(RecursionDepth());
// We should only ever get here from PerformMicroTaskCheckPoint after a task or other
// checkpoint-able state, never from within ProcessStableStateQueue (mDoingStableStates==false).
// However, some buggy XUL addons may dispatch JS Events from runnables in the StableState queue,
// which then perform a checkpoint at their end, ending up here while ProcessStableStateQueue is
// on the stack.
// Specifically catch that here and add the call to CleanupIDBTransactions to the outer queue, to
// be performed when we know we're in a "regular" stable state again.
if (!mDoingStableStates) {
CleanupIDBTransactions(RecursionDepth());
} else {
// Don't need a RefPtr to this here as we know this->ProcessStableStateQueue is on the stack
nsCOMPtr<nsIRunnable> cleanupRunnable = NS_NewRunnableFunction(
[this, rec = RecursionDepth()] {
MOZ_ASSERT(mDoingStableStates);
// As this is called from ProcessStableStateQueue, mDoingStableStates == true.
// Switch the flag while CleanupIDBTransactions executes.
mDoingStableStates = false;
CleanupIDBTransactions(rec);
mDoingStableStates = true;
});
RunInStableState(cleanupRunnable.forget());
};
}
uint32_t