зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1713320, ensure idle tasks get run, r=bas
If IdleTaskManager is suspended and non-idle task _is_run_, nothing seems to guarantee idle tasks get run later. Calling UpdateCachedIdleDeadline triggers child->parent->child ipc messages if needed and ends up enabling IdleTaskManager. Differential Revision: https://phabricator.services.mozilla.com/D116316
This commit is contained in:
Родитель
5b9b440b1f
Коммит
73bad4abf2
|
@ -711,6 +711,7 @@ skip-if = xorigin # JavaScript error: http://mochi.test:8888/tests/SimpleTest/Si
|
|||
[test_NodeIterator_mutations_1.xhtml]
|
||||
[test_NodeIterator_mutations_2.html]
|
||||
[test_NodeIterator_mutations_3.html]
|
||||
[test_nested_event_loop_spin_and_idle_tasks.html]
|
||||
[test_nodelist_holes.html]
|
||||
[test_open_null_features.html]
|
||||
[test_openDialogChromeOnly.html]
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Nested event loop spinning and idle task handling</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
||||
<script>
|
||||
if (!location.search.includes("newpage")) {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var win = window.open(this.location + "?newpage");
|
||||
win.onload = function() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
// Spin the event loop using a synchronous XMLHttpRequest.
|
||||
xhr.open("GET", "slow.sjs", false);
|
||||
xhr.send();
|
||||
ok(win.didRunIdleCallback, "Should have run an idle callback.");
|
||||
win.close();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
} else {
|
||||
var didRunIdleCallback = false;
|
||||
requestIdleCallback(function() {
|
||||
didRunIdleCallback = true;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</html>
|
|
@ -72,6 +72,13 @@ class IdlePeriodState {
|
|||
mCachedIdleDeadline = GetIdleDeadlineInternal(false, aProofOfUnlock);
|
||||
}
|
||||
|
||||
// If we have local idle deadline, but don't have an idle token, this will
|
||||
// request such from the parent process when this is called in a child
|
||||
// process.
|
||||
void RequestIdleDeadlineIfNeeded(const MutexAutoUnlock& aProofOfUnlock) {
|
||||
GetIdleDeadlineInternal(false, aProofOfUnlock);
|
||||
}
|
||||
|
||||
// Reset our cached idle deadline, so we stop allowing idle runnables to run.
|
||||
void ClearCachedIdleDeadline() { mCachedIdleDeadline = TimeStamp(); }
|
||||
|
||||
|
|
|
@ -620,6 +620,25 @@ bool TaskController::ExecuteNextTaskOnlyMainThreadInternal(
|
|||
do {
|
||||
taskRan = DoExecuteNextTaskOnlyMainThreadInternal(aProofOfLock);
|
||||
if (taskRan) {
|
||||
if (mIdleTaskManager && mIdleTaskManager->mTaskCount &&
|
||||
mIdleTaskManager->IsSuspended(aProofOfLock)) {
|
||||
uint32_t activeTasks = mMainThreadTasks.size();
|
||||
for (TaskManager* manager : mTaskManagers) {
|
||||
if (manager->IsSuspended(aProofOfLock)) {
|
||||
activeTasks -= manager->mTaskCount;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!activeTasks) {
|
||||
// We have only idle (and maybe other suspended) tasks left, so need
|
||||
// to update the idle state. We need to temporarily release the lock
|
||||
// while we do that.
|
||||
MutexAutoUnlock unlock(mGraphMutex);
|
||||
mIdleTaskManager->State().RequestIdleDeadlineIfNeeded(unlock);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче