Bug 1682866 - Always use normal priority for DelayedDeleteRunnable r=smaug

DelayedDeleteRunnable would schedule itself twice and use input priority
for the second time because it only wants to run after everything
that could possibly touch this tab. This was needed because we were
strict with IPC messages. However, this is no longer needed because
IPC messages with destroyed actors will be discarded nowadays, so
we don't have to use input priority anymore.

Another reason for making this change is that input events could be
suspended when the runnable is about to run, so we need to either
use a different priority or resume input events.

Differential Revision: https://phabricator.services.mozilla.com/D100345
This commit is contained in:
Sean Feng 2020-12-22 17:56:28 +00:00
parent 01b6711440
commit 851fe92332
7 changed files with 77 additions and 10 deletions

View File

@ -6464,7 +6464,7 @@ void nsGlobalWindowOuter::LeaveModalState() {
nsGlobalWindowOuter* topWin = GetInProcessScriptableTopInternal();
if (!topWin) {
NS_ERROR("Uh, LeaveModalState() called w/o a reachable top window?");
NS_WARNING("Uh, LeaveModalState() called w/o a reachable top window?");
return;
}

View File

@ -223,12 +223,8 @@ class BrowserChild::DelayedDeleteRunnable final : public Runnable,
public nsIRunnablePriority {
RefPtr<BrowserChild> mBrowserChild;
// In order to ensure that this runnable runs after everything that could
// possibly touch this tab, we send it through the event queue twice. The
// first time it runs at normal priority and the second time it runs at
// input priority. This ensures that it runs after all events that were in
// either queue at the time it was first dispatched. mReadyToDelete starts
// out false (when it runs at normal priority) and is then set to true.
// In order to try that this runnable runs after everything that could
// possibly touch this tab, we send it through the event queue twice.
bool mReadyToDelete = false;
public:
@ -248,8 +244,7 @@ class BrowserChild::DelayedDeleteRunnable final : public Runnable,
}
NS_IMETHOD GetPriority(uint32_t* aPriority) override {
*aPriority = mReadyToDelete ? nsIRunnablePriority::PRIORITY_INPUT_HIGH
: nsIRunnablePriority::PRIORITY_NORMAL;
*aPriority = nsIRunnablePriority::PRIORITY_NORMAL;
return NS_OK;
}

View File

@ -6,6 +6,8 @@
MOCHITEST_MANIFESTS += ["test/mochitest.ini"]
BROWSER_CHROME_MANIFESTS += ["test/browser.ini"]
XPIDL_SOURCES += [
"nsIAlertsService.idl",
]

View File

@ -1,5 +1,5 @@
"use strict";
module.exports = {
extends: ["plugin:mozilla/mochitest-test"],
extends: ["plugin:mozilla/mochitest-test", "plugin:mozilla/browser-test"],
};

View File

@ -0,0 +1,5 @@
[browser_bug1682866.js]
skip-if = !fission
support-files =
file_bug1682866.html

View File

@ -0,0 +1,56 @@
const baseURL = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"http://example.com"
);
const alertURL = `${baseURL}file_bug1682866.html`;
add_task(async function testAlertForceClosed() {
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
alertURL,
true /* waitForLoad */
);
// Open a second which is in the same process as tab
let secondTabIsLoaded = BrowserTestUtils.waitForNewTab(
gBrowser,
alertURL,
true,
false
);
let isSuspendedAfterAlert = await SpecialPowers.spawn(
tab.linkedBrowser.browsingContext,
[alertURL],
url => {
content.open(url);
var utils = SpecialPowers.getDOMWindowUtils(content);
return utils.isInputTaskManagerSuspended;
}
);
await secondTabIsLoaded;
let secondTab = gBrowser.tabs[2];
is(
isSuspendedAfterAlert,
true,
"InputTaskManager should be suspended because alert is opened"
);
let alertClosed = BrowserTestUtils.waitForEvent(
tab.linkedBrowser,
"DOMModalDialogClosed"
);
BrowserTestUtils.loadURI(tab.linkedBrowser, "about:newtab");
await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
await alertClosed;
gBrowser.removeTab(tab);
gBrowser.removeTab(secondTab);
});

View File

@ -0,0 +1,9 @@
<html>
<body>
<script>
window.onload = function() {
alert("This is an alert");
}
</script>
</body>
</html>