Bug 1223766 - Removing an actor from an actor pool should destroy it;r=past
authorEddy Bruel <ejpbruel@mozilla.com>
Fri, 13 Nov 2015 10:19:55 +0100
changeset 308703 3da6ad8bb8a99becd01f23da263d0e7496c3d5e6
parent 308702 e23d0660a042e6a00a1de55667cc9b30c63620d7
child 308704 d6d640c4b8c2097f3a780f6420c197dc698a8183
push id7514
push users.kaspari@gmail.com
push dateFri, 13 Nov 2015 14:12:41 +0000
reviewerspast
bugs1223766
milestone45.0a1
Bug 1223766 - Removing an actor from an actor pool should destroy it;r=past
devtools/server/actors/common.js
devtools/server/main.js
--- a/devtools/server/actors/common.js
+++ b/devtools/server/actors/common.js
@@ -208,49 +208,64 @@ exports.appendExtraActors = function app
  *
  * ActorPools are actorID -> actor mapping and storage.  These are
  * used to accumulate and quickly dispose of groups of actors that
  * share a lifetime.
  */
 function ActorPool(aConnection)
 {
   this.conn = aConnection;
-  this._cleanups = {};
   this._actors = {};
 }
 
 ActorPool.prototype = {
   /**
-   * Add an actor to the actor pool.  If the actor doesn't have an ID,
-   * allocate one from the connection.
+   * Destroy the pool. This will remove all actors from the pool.
+   */
+  destroy: function AP_destroy() {
+    for (let id in this._actors) {
+      this.removeActor(this._actors[id]);
+    }
+  },
+
+  /**
+   * Add an actor to the pool. If the actor doesn't have an ID, allocate one
+   * from the connection.
    *
-   * @param aActor object
-   *        The actor implementation.  If the object has a
-   *        'disconnect' property, it will be called when the actor
-   *        pool is cleaned up.
+   * @param Object aActor
+   *        The actor to be added to the pool.
    */
   addActor: function AP_addActor(aActor) {
     aActor.conn = this.conn;
     if (!aActor.actorID) {
       let prefix = aActor.actorPrefix;
       if (!prefix && typeof aActor == "function") {
         // typeName is a convention used with protocol.js-based actors
         prefix = aActor.prototype.actorPrefix || aActor.prototype.typeName;
       }
       aActor.actorID = this.conn.allocID(prefix || undefined);
     }
 
+    // If the actor is already in a pool, remove it without destroying it.
     if (aActor.registeredPool) {
-      aActor.registeredPool.removeActor(aActor);
+      delete aActor.registeredPool._actors[aActor.actorID];
     }
     aActor.registeredPool = this;
 
     this._actors[aActor.actorID] = aActor;
+  },
+
+  /**
+   * Remove an actor from the pool. If the actor has a disconnect method, call
+   * it.
+   */
+  removeActor: function AP_remove(aActor) {
+    delete this._actors[aActor.actorID];
     if (aActor.disconnect) {
-      this._cleanups[aActor.actorID] = aActor;
+      aActor.disconnect();
     }
   },
 
   get: function AP_get(aActorID) {
     return this._actors[aActorID] || undefined;
   },
 
   has: function AP_has(aActorID) {
@@ -260,40 +275,22 @@ ActorPool.prototype = {
   /**
    * Returns true if the pool is empty.
    */
   isEmpty: function AP_isEmpty() {
     return Object.keys(this._actors).length == 0;
   },
 
   /**
-   * Remove an actor from the actor pool.
-   */
-  removeActor: function AP_remove(aActor) {
-    delete this._actors[aActor.actorID];
-    delete this._cleanups[aActor.actorID];
-  },
-
-  /**
    * Match the api expected by the protocol library.
    */
   unmanage: function(aActor) {
     return this.removeActor(aActor);
   },
 
-  /**
-   * Run all actor cleanups.
-   */
-  cleanup: function AP_cleanup() {
-    for (let id in this._cleanups) {
-      this._cleanups[id].disconnect();
-    }
-    this._cleanups = {};
-  },
-
   forEach: function(callback) {
     for (let name in this._actors) {
       callback(this._actors[name]);
     }
   },
 }
 
 exports.ActorPool = ActorPool;
--- a/devtools/server/main.js
+++ b/devtools/server/main.js
@@ -1382,17 +1382,17 @@ DebuggerServerConnection.prototype = {
    *        True if you don't want to disconnect each actor from the pool, false
    *        otherwise.
    */
   removeActorPool: function DSC_removeActorPool(aActorPool, aNoCleanup) {
     let index = this._extraPools.lastIndexOf(aActorPool);
     if (index > -1) {
       let pool = this._extraPools.splice(index, 1);
       if (!aNoCleanup) {
-        pool.map(function(p) { p.cleanup(); });
+        pool.map(function(p) { p.destroy(); });
       }
     }
   },
 
   /**
    * Add an actor to the default actor pool for this connection.
    */
   addActor: function DSC_addActor(aActor) {
@@ -1697,17 +1697,17 @@ DebuggerServerConnection.prototype = {
     dumpn("Cleaning up connection.");
     if (!this._actorPool) {
       // Ignore this call if the connection is already closed.
       return;
     }
     events.emit(this, "closed", aStatus);
 
     this._actorPool = null;
-    this._extraPools.map(function(p) { p.cleanup(); });
+    this._extraPools.map(function(p) { p.destroy(); });
     this._extraPools = null;
 
     this.rootActor = null;
     this._transport = null;
     DebuggerServer._connectionClosed(this);
   },
 
   /*