зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1602741 - Ensure shell drainJobQueue() function always drains the job queue r=sfink
Previously this wouldn't drain any jobs queued by FinalizationGroup callbacks. Differential Revision: https://phabricator.services.mozilla.com/D56538 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
3292e920dc
Коммит
47fa72c92f
|
@ -0,0 +1,26 @@
|
||||||
|
// |jit-test| --enable-weak-refs
|
||||||
|
|
||||||
|
// Test that drainJobQueue() drains all jobs, including those queued
|
||||||
|
// by FinalizationGroup callbacks.
|
||||||
|
|
||||||
|
let finalizeRan = false;
|
||||||
|
let promiseRan = false;
|
||||||
|
|
||||||
|
let fg = new FinalizationGroup(() => {
|
||||||
|
finalizeRan = true;
|
||||||
|
Promise.resolve().then(() => {
|
||||||
|
promiseRan = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
fg.register({}, {});
|
||||||
|
|
||||||
|
gc();
|
||||||
|
|
||||||
|
assertEq(finalizeRan, false);
|
||||||
|
assertEq(promiseRan, false);
|
||||||
|
|
||||||
|
drainJobQueue();
|
||||||
|
|
||||||
|
assertEq(finalizeRan, true);
|
||||||
|
assertEq(promiseRan, true);
|
|
@ -1030,13 +1030,16 @@ static void ShellCleanupFinalizationGroupCallback(JSObject* group, void* data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MaybeRunFinalizationGroupCleanupTasks(JSContext* cx) {
|
// Run any FinalizationGroup cleanup tasks and return whether any ran.
|
||||||
|
static bool MaybeRunFinalizationGroupCleanupTasks(JSContext* cx) {
|
||||||
ShellContext* sc = GetShellContext(cx);
|
ShellContext* sc = GetShellContext(cx);
|
||||||
MOZ_ASSERT(!sc->quitting);
|
MOZ_ASSERT(!sc->quitting);
|
||||||
|
|
||||||
Rooted<ShellContext::ObjectVector> groups(cx);
|
Rooted<ShellContext::ObjectVector> groups(cx);
|
||||||
std::swap(groups.get(), sc->finalizationGroupsToCleanUp.get());
|
std::swap(groups.get(), sc->finalizationGroupsToCleanUp.get());
|
||||||
|
|
||||||
|
bool ranTasks = false;
|
||||||
|
|
||||||
RootedObject group(cx);
|
RootedObject group(cx);
|
||||||
for (const auto& g : groups) {
|
for (const auto& g : groups) {
|
||||||
group = g;
|
group = g;
|
||||||
|
@ -1048,10 +1051,14 @@ static void MaybeRunFinalizationGroupCleanupTasks(JSContext* cx) {
|
||||||
mozilla::Unused << JS::CleanupQueuedFinalizationGroup(cx, group);
|
mozilla::Unused << JS::CleanupQueuedFinalizationGroup(cx, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ranTasks = true;
|
||||||
|
|
||||||
if (sc->quitting) {
|
if (sc->quitting) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ranTasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool EnqueueJob(JSContext* cx, unsigned argc, Value* vp) {
|
static bool EnqueueJob(JSContext* cx, unsigned argc, Value* vp) {
|
||||||
|
@ -1074,14 +1081,19 @@ static void RunShellJobs(JSContext* cx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run microtasks.
|
while (true) {
|
||||||
js::RunJobs(cx);
|
// Run microtasks.
|
||||||
if (sc->quitting) {
|
js::RunJobs(cx);
|
||||||
return;
|
if (sc->quitting) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Run tasks (only finalization group clean tasks are possible).
|
// Run tasks (only finalization group clean tasks are possible).
|
||||||
MaybeRunFinalizationGroupCleanupTasks(cx);
|
bool ranTasks = MaybeRunFinalizationGroupCleanupTasks(cx);
|
||||||
|
if (!ranTasks) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool DrainJobQueue(JSContext* cx, unsigned argc, Value* vp) {
|
static bool DrainJobQueue(JSContext* cx, unsigned argc, Value* vp) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче