Bug 792846 - SystemMessageInternal.js fails if one of the message receiver is closed. r=vingtetun
authorGregor Wagner <anygregor@gmail.com>
Wed, 26 Sep 2012 11:06:25 -0700
changeset 108270 8f0b50af10510a9a3fb0450d528e8f9fc4031150
parent 108269 8fc98a70f97a5f3a91e08d133660d49793e48e66
child 108271 3dfca392c32b0357f6a65329decd3abc5528395c
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersvingtetun
bugs792846
milestone18.0a1
Bug 792846 - SystemMessageInternal.js fails if one of the message receiver is closed. r=vingtetun
dom/apps/src/Webapps.jsm
dom/messages/SystemMessageInternal.js
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -492,20 +492,30 @@ let DOMApplicationRegistry = {
   // Webapps:RemoveApp
   // Webapps:Install:Return:OK
   // Webapps:Uninstall:Return:OK
   // Webapps:OfflineCache
   broadcastMessage: function broadcastMessage(aMsgName, aContent) {
     if (!(aMsgName in this.children)) {
       return;
     }
-
-    this.children[aMsgName].forEach(function _doBroadcast(aMsgMgr) {
-      aMsgMgr.sendAsyncMessage(aMsgName, aContent);
-    });
+    let i;
+    for (i = this.children[aMsgName].length - 1; i >= 0; i -= 1) {
+      let msgMgr = this.children[aMsgName][i];
+      try {
+        msgMgr.sendAsyncMessage(aMsgName, aContent);
+      } catch (e) {
+        // Remove once 777508 lands.
+        let index;
+        if ((index = this.children[aMsgName].indexOf(msgMgr)) != -1) {
+          this.children[aMsgName].splice(index, 1);
+          dump("Remove dead MessageManager!\n");
+        }
+      }
+    };
   },
 
   _getAppDir: function(aId) {
     return FileUtils.getDir(DIRECTORY_NAME, ["webapps", aId], true, true);
   },
 
   _writeFile: function ss_writeFile(aFile, aData, aCallbak) {
     // Initialize the file output stream.
--- a/dom/messages/SystemMessageInternal.js
+++ b/dom/messages/SystemMessageInternal.js
@@ -45,22 +45,34 @@ function SystemMessageInternal() {
     ppmm.addMessageListener(aMsg, this);
   }).bind(this));
 }
 
 SystemMessageInternal.prototype = {
   sendMessage: function sendMessage(aType, aMessage, aPageURI, aManifestURI) {
     debug("Broadcasting " + aType + " " + JSON.stringify(aMessage));
     if (this._listeners[aManifestURI.spec]) {
-      this._listeners[aManifestURI.spec].forEach(function sendMsg(aListener) {
-        aListener.sendAsyncMessage("SystemMessageManager:Message",
-                                   { type: aType,
-                                     msg: aMessage,
-                                     manifest: aManifestURI.spec })
-      });
+      let i;
+      let listener;
+      for (i = this._listeners[aManifestURI.spec].length - 1; i >= 0; i -= 1) {
+        listener = this._listeners[aManifestURI.spec][i];
+        try {
+          listener.sendAsyncMessage("SystemMessageManager:Message",
+                                     { type: aType,
+                                       msg: aMessage,
+                                       manifest: aManifestURI.spec })
+        } catch (e) {
+          // Remove once 777508 lands.
+          let index;
+          if ((index = this._listeners[aManifestURI.spec].indexOf(listener)) != -1) {
+            this._listeners[aManifestURI.spec].splice(index, 1);
+            dump("Remove dead MessageManager!\n");
+          }
+        }
+      };
     }
 
     this._pages.forEach(function sendMess_openPage(aPage) {
       if (aPage.type != aType ||
           aPage.manifest != aManifestURI.spec ||
           aPage.uri != aPageURI.spec) {
         return;
       }
@@ -70,22 +82,33 @@ SystemMessageInternal.prototype = {
   },
 
   broadcastMessage: function broadcastMessage(aType, aMessage) {
     debug("Broadcasting " + aType + " " + JSON.stringify(aMessage));
     // Find pages that registered an handler for this type.
     this._pages.forEach(function(aPage) {
       if (aPage.type == aType) {
         if (this._listeners[aPage.manifest]) {
-          this._listeners[aPage.manifest].forEach(function sendMsg(aListener) {
-            aListener.sendAsyncMessage("SystemMessageManager:Message",
-                                       { type: aType,
-                                         msg: aMessage,
-                                         manifest: aPage.manifest})
-          });
+          let i;
+          for (i = this._listeners[aPage.manifest].length - 1; i >= 0; i -= 1) {
+            let listener = this._listeners[aPage.manifest][i];
+            try {
+              listener.sendAsyncMessage("SystemMessageManager:Message",
+                                         { type: aType,
+                                           msg: aMessage,
+                                           manifest: aPage.manifest})
+            } catch (e) {
+              // Remove once 777508 lands.
+              let index;
+              if ((index = this._listeners[aPage.manifest].indexOf(listener)) != -1) {
+                this._listeners[aPage.manifest].splice(index, 1);
+                dump("Remove dead MessageManager!\n");
+              }
+            }
+          };
         }
         this._processPage(aPage, aMessage);
       }
     }.bind(this))
   },
 
   registerPage: function registerPage(aType, aPageURI, aManifestURI) {
     if (!aPageURI || !aManifestURI) {