Bug 1550467 - Ensure that listeners in chrome scripts are cleaned up. r=botond,jmaher

Apparently leaving these listeners registered can leak DOM windows
(in some circumstances that I don't fully comprehend) which causes
test failures when running on debug builds. At any rate, unregistering
listeners on cleanup seems like a good thing to do.

Differential Revision: https://phabricator.services.mozilla.com/D32185

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Kartikaya Gupta 2019-06-06 20:49:25 +00:00
parent afed87d54e
commit aef7a3eaeb
2 changed files with 22 additions and 4 deletions

View File

@ -378,7 +378,7 @@ async function waitUntilApzStable() {
// it must be totally self-contained to be shipped over to the parent process.
/* eslint-env mozilla/frame-script */
function parentProcessFlush() {
addMessageListener("apz-flush", function() {
function apzFlush() {
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
var topWin = Services.wm.getMostRecentWindow("navigator:browser");
if (!topWin) {
@ -409,13 +409,23 @@ async function waitUntilApzStable() {
// Flush APZ repaints, but wait until all the pending paints have been
// sent.
flushRepaint();
});
}
function cleanup() {
removeMessageListener("apz-flush", apzFlush);
removeMessageListener("cleanup", cleanup);
}
addMessageListener("apz-flush", apzFlush);
addMessageListener("cleanup", cleanup);
}
// This is the first time waitUntilApzStable is being called, do initialization
if (typeof waitUntilApzStable.chromeHelper == "undefined") {
waitUntilApzStable.chromeHelper = SpecialPowers.loadChromeScript(parentProcessFlush);
ApzCleanup.register(() => { waitUntilApzStable.chromeHelper.destroy(); });
ApzCleanup.register(() => {
waitUntilApzStable.chromeHelper.sendSyncMessage("cleanup", null);
waitUntilApzStable.chromeHelper.destroy();
delete waitUntilApzStable.chromeHelper;
});
}
// Actually trigger the parent-process flush and wait for it to finish

View File

@ -466,7 +466,7 @@ SpecialPowersObserverAPI.prototype = {
}
// Setup a chrome sandbox that has access to sendAsyncMessage
// and addMessageListener in order to communicate with
// and {add,remove}MessageListener in order to communicate with
// the mochitest.
let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
let sandboxOptions = Object.assign({wantGlobalProperties: ["ChromeUtils"]},
@ -481,6 +481,14 @@ SpecialPowersObserverAPI.prototype = {
sb.addMessageListener = (name, listener) => {
this._chromeScriptListeners.push({ id, name, listener });
};
sb.removeMessageListener = (name, listener) => {
let index = this._chromeScriptListeners.findIndex(function(obj) {
return obj.id == id && obj.name == name && obj.listener == listener;
});
if (index >= 0) {
this._chromeScriptListeners.splice(index, 1);
}
};
sb.browserElement = aMessage.target;
// Also expose assertion functions