Bug 1302148 - Fix potential race in toolbox.destroy. r=bgrins
authorAlexandre Poirot <poirot.alex@gmail.com>
Mon, 12 Sep 2016 02:44:17 -0700
changeset 314486 1fdbce2821b589bff8e03407712646f7c6716756
parent 314485 d0b6ed087223c1be7d9ce55bfc4dbd663551dd32
child 314487 ee364270d3e60a036a5767bae738e9ee6cae5e81
push id81903
push usercbook@mozilla.com
push dateTue, 20 Sep 2016 10:04:26 +0000
treeherdermozilla-inbound@150109898e5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgrins
bugs1302148
milestone51.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1302148 - Fix potential race in toolbox.destroy. r=bgrins MozReview-Commit-ID: 8qSwjLVrRL6
devtools/client/framework/toolbox.js
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -2043,16 +2043,18 @@ Toolbox.prototype = {
    * Remove all UI elements, detach from target and clear up
    */
   destroy: function () {
     // If several things call destroy then we give them all the same
     // destruction promise so we're sure to destroy only once
     if (this._destroyer) {
       return this._destroyer;
     }
+    let deferred = defer();
+    this._destroyer = deferred.promise;
 
     this.emit("destroy");
 
     this._target.off("navigate", this._refreshHostTitle);
     this._target.off("frame-update", this._updateFrames);
     this.off("select", this._refreshHostTitle);
     this.off("host-changed", this._refreshHostTitle);
     this.off("ready", this._showDevEditionPromo);
@@ -2138,17 +2140,17 @@ Toolbox.prototype = {
       CommandUtils.destroyRequisition(this._requisition, this.target);
     }
     this._telemetry.toolClosed("toolbox");
     this._telemetry.destroy();
 
     // Finish all outstanding tasks (which means finish destroying panels and
     // then destroying the host, successfully or not) before destroying the
     // target.
-    this._destroyer = settleAll(outstanding)
+    deferred.resolve(settleAll(outstanding)
         .catch(console.error)
         .then(() => this.destroyHost())
         .catch(console.error)
         .then(() => {
           this._win = null;
 
           // Targets need to be notified that the toolbox is being torn down.
           // This is done after other destruction tasks since it may tear down
@@ -2172,17 +2174,17 @@ Toolbox.prototype = {
 
           // Force GC to prevent long GC pauses when running tests and to free up
           // memory in general when the toolbox is closed.
           if (flags.testing) {
             win.QueryInterface(Ci.nsIInterfaceRequestor)
               .getInterface(Ci.nsIDOMWindowUtils)
               .garbageCollect();
           }
-        }).then(null, console.error);
+        }).then(null, console.error));
 
     let leakCheckObserver = ({wrappedJSObject: barrier}) => {
       // Make the leak detector wait until this toolbox is properly destroyed.
       barrier.client.addBlocker("DevTools: Wait until toolbox is destroyed",
                                 this._destroyer);
     };
 
     let topic = "shutdown-leaks-before-check";