Bug 1056342 - Performance tab fails with app after second toolbox open, r=paul
authorVictor Porof <vporof@mozilla.com>
Fri, 03 Oct 2014 21:40:42 +0100
changeset 231960 085f6067705d89dc7df04d374ec81d1f8bc5068b
parent 231959 b55a1862af311e41171fb0440888e74463ace0b0
child 231961 b28e496d535b80d31c00d3561514e6d5dd9f55fa
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspaul
bugs1056342
milestone35.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 1056342 - Performance tab fails with app after second toolbox open, r=paul
browser/devtools/profiler/panel.js
browser/devtools/profiler/utils/shared.js
--- a/browser/devtools/profiler/panel.js
+++ b/browser/devtools/profiler/panel.js
@@ -30,22 +30,22 @@ exports.ProfilerPanel = ProfilerPanel;
 ProfilerPanel.prototype = {
   /**
    * Open is effectively an asynchronous constructor.
    *
    * @return object
    *         A promise that is resolved when the Profiler completes opening.
    */
   open: Task.async(function*() {
-    let connection = getProfilerConnection(this._toolbox);
-    yield connection.open();
+    this._connection = getProfilerConnection(this._toolbox);
+    yield this._connection.open();
 
     this.panelWin.gToolbox = this._toolbox;
     this.panelWin.gTarget = this.target;
-    this.panelWin.gFront = new ProfilerFront(connection);
+    this.panelWin.gFront = new ProfilerFront(this._connection);
     yield this.panelWin.startupProfiler();
 
     this.isReady = true;
     this.emit("ready");
     return this;
   }),
 
   // DevToolPanel API
@@ -54,12 +54,16 @@ ProfilerPanel.prototype = {
 
   destroy: Task.async(function*() {
     // Make sure this panel is not already destroyed.
     if (this._destroyed) {
       return;
     }
 
     yield this.panelWin.shutdownProfiler();
+
+    // Destroy the connection to ensure packet handlers are removed from client.
+    this._connection.destroy();
+
     this.emit("destroyed");
     this._destroyed = true;
   })
 };
--- a/browser/devtools/profiler/utils/shared.js
+++ b/browser/devtools/profiler/utils/shared.js
@@ -108,37 +108,54 @@ ProfilerConnection.prototype = {
 
     this._connectMiscActors();
     this._connected = true;
 
     Services.obs.notifyObservers(null, "profiler-connection-opened", null);
   }),
 
   /**
+   * Destroys this connection.
+   */
+  destroy: function() {
+    this._disconnectMiscActors();
+    this._connected = false;
+  },
+
+  /**
    * Initializes a connection to miscellaneous actors which are going to be
    * used in tandem with the profiler actor.
    */
   _connectMiscActors: function() {
     // Only initialize the framerate front if the respective actor is available.
     // Older Gecko versions don't have an existing implementation, in which case
     // all the methods we need can be easily mocked.
     if (this._target.form && this._target.form.framerateActor) {
       this._framerate = new FramerateFront(this._target.client, this._target.form);
     } else {
       this._framerate = {
+        destroy: () => {},
         startRecording: () => {},
         stopRecording: () => {},
         cancelRecording: () => {},
         isRecording: () => false,
         getPendingTicks: () => null
       };
     }
   },
 
   /**
+   * Closes the connections to miscellaneous actors.
+   * @see ProfilerConnection.prototype._connectMiscActors
+   */
+  _disconnectMiscActors: function() {
+    this._framerate.destroy();
+  },
+
+  /**
    * Sends the request over the remote debugging protocol to the
    * specified actor.
    *
    * @param string actor
    *        The designated actor. Currently supported: "profiler", "framerate".
    * @param string method
    *        Method to call on the backend.
    * @param any args [optional]