Bug 1353559 - Filter out exited browsers from tab list. r=ochameau
This adds higher level protection to ignore exited browser actors, so we don't
end up triggering methods like `form` on them, since they won't make much sense
anyway.
MozReview-Commit-ID: KgUCA04N2fY
--- a/devtools/server/actors/root.js
+++ b/devtools/server/actors/root.js
@@ -270,16 +270,20 @@ RootActor.prototype = {
* retiring any actors that didn't get listed again, and preparing any
* new actors to receive packets.
*/
let newActorPool = new ActorPool(this.conn);
let tabActorList = [];
let selected;
return tabList.getList().then((tabActors) => {
for (let tabActor of tabActors) {
+ if (tabActor.exited) {
+ // Tab actor may have exited while we were gathering the list.
+ continue;
+ }
if (tabActor.selected) {
selected = tabActorList.length;
}
tabActor.parentID = this.actorID;
newActorPool.addActor(tabActor);
tabActorList.push(tabActor);
}
/* DebuggerServer.addGlobalActor support: create actors. */
--- a/devtools/server/actors/webbrowser.js
+++ b/devtools/server/actors/webbrowser.js
@@ -695,29 +695,30 @@ exports.BrowserTabList = BrowserTabList;
*
* @param connection The main RDP connection.
* @param browser <xul:browser> or <iframe mozbrowser> element to connect to.
*/
function BrowserTabActor(connection, browser) {
this._conn = connection;
this._browser = browser;
this._form = null;
+ this.exited = false;
}
BrowserTabActor.prototype = {
connect() {
let onDestroy = () => {
if (this._deferredUpdate) {
// Reject the update promise if the tab was destroyed while requesting an update
this._deferredUpdate.reject({
error: "tabDestroyed",
message: "Tab destroyed while performing a BrowserTabActor update"
});
}
- this._form = null;
+ this.exit();
};
let connect = DebuggerServer.connectToChild(this._conn, this._browser, onDestroy);
return connect.then(form => {
this._form = form;
return this;
});
},
@@ -734,17 +735,17 @@ BrowserTabActor.prototype = {
return this._browser.messageManager ||
this._browser.frameLoader.messageManager;
},
update() {
// If the child happens to be crashed/close/detach, it won't have _form set,
// so only request form update if some code is still listening on the other
// side.
- if (this._form) {
+ if (!this.exited) {
this._deferredUpdate = promise.defer();
let onFormUpdate = msg => {
// There may be more than just one childtab.js up and running
if (this._form.actor != msg.json.actor) {
return;
}
this._mm.removeMessageListener("debug:form", onFormUpdate);
this._form = msg.json;
@@ -808,16 +809,18 @@ BrowserTabActor.prototype = {
if (!form.url) {
form.url = this.url;
}
return form;
},
exit() {
this._browser = null;
+ this._form = null;
+ this.exited = true;
},
};
exports.BrowserTabActor = BrowserTabActor;
function BrowserAddonList(connection) {
this._connection = connection;
this._actorByAddonId = new Map();