Bug 874339 - System Message API: redundant queues are created for the pending "activity" system messages r=gene
authorFabrice Desré <fabrice@mozilla.com>
Sun, 16 Jun 2013 21:16:21 -0700
changeset 146719 5fcd3e7dc80936599a33b0fe3ccb8d6e006c72ce
parent 146718 6304b8fd16fe77b4fb67f24ceed0cf11c30313fc
child 146720 dfae1419f8ec71f4cac44cbae0e2a245ea80d5a6
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgene
bugs874339
milestone24.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 874339 - System Message API: redundant queues are created for the pending "activity" system messages r=gene
dom/messages/SystemMessageInternal.js
--- a/dom/messages/SystemMessageInternal.js
+++ b/dom/messages/SystemMessageInternal.js
@@ -123,16 +123,27 @@ SystemMessageInternal.prototype = {
       if (cpuWakeLock.lockCount <= 0) {
         debug("Unlocking the CPU wake lock now that the system messages " +
               "have been successfully handled by its registered page.");
         this._cancelCpuWakeLock(aPageKey);
       }
     }
   },
 
+  _findPage: function _findPage(aType, aPageURL, aManifestURL) {
+    let page = null;
+    this._pages.some(function(aPage) {
+      if (this._isPageMatched(aPage, aType, aPageURL, aManifestURL)) {
+        page = aPage;
+      }
+      return page !== null;
+    }, this);
+    return page;
+  },
+
   sendMessage: function sendMessage(aType, aMessage, aPageURI, aManifestURI) {
     // Buffer system messages until the webapps' registration is ready,
     // so that we can know the correct pages registered to be sent.
     if (!this._webappsRegistryReady) {
       this._bufferedSysMsgs.push({ how: "send",
                                    type: aType,
                                    msg: aMessage,
                                    pageURI: aPageURI,
@@ -152,33 +163,24 @@ SystemMessageInternal.prototype = {
     if (!this._sendMessageCommon(aType,
                                  aMessage,
                                  messageID,
                                  aPageURI.spec,
                                  aManifestURI.spec)) {
       return;
     }
 
-    let pagesToOpen = {};
-    this._pages.forEach(function(aPage) {
-      if (!this._isPageMatched(aPage, aType, aPageURI.spec, aManifestURI.spec)) {
-        return;
-      }
-
+    let page = this._findPage(aType, aPageURI.spec, aManifestURI.spec);
+    if (page) {
       // Queue this message in the corresponding pages.
-      this._queueMessage(aPage, aMessage, messageID);
+      this._queueMessage(page, aMessage, messageID);
 
       // Open app pages to handle their pending messages.
-      // Note that we only need to open each app page once.
-      let key = this._createKeyForPage(aPage);
-      if (!pagesToOpen.hasOwnProperty(key)) {
-        this._openAppPage(aPage, aMessage);
-        pagesToOpen[key] = true;
-      }
-    }, this);
+      this._openAppPage(page, aMessage);
+    }
   },
 
   broadcastMessage: function broadcastMessage(aType, aMessage) {
     // Buffer system messages until the webapps' registration is ready,
     // so that we can know the correct pages registered to be broadcasted.
     if (!this._webappsRegistryReady) {
       this._bufferedSysMsgs.push({ how: "broadcast",
                                    type: aType,
@@ -187,51 +189,56 @@ SystemMessageInternal.prototype = {
     }
 
     // Give this message an ID so that we can identify the message and
     // clean it up from the pending message queue when apps receive it.
     let messageID = gUUIDGenerator.generateUUID().toString();
 
     debug("Broadcasting " + aType + " " + JSON.stringify(aMessage));
     // Find pages that registered an handler for this type.
-    let pagesToOpen = {};
     this._pages.forEach(function(aPage) {
       if (aPage.type == aType) {
         // Don't need to open the pages and queue the system message
         // which was not allowed to be sent.
         if (!this._sendMessageCommon(aType,
                                      aMessage,
                                      messageID,
                                      aPage.uri,
                                      aPage.manifest)) {
           return;
         }
 
         // Queue this message in the corresponding pages.
         this._queueMessage(aPage, aMessage, messageID);
 
         // Open app pages to handle their pending messages.
-        // Note that we only need to open each app page once.
-        let key = this._createKeyForPage(aPage);
-        if (!pagesToOpen.hasOwnProperty(key)) {
-          this._openAppPage(aPage, aMessage);
-          pagesToOpen[key] = true;
-        }
+        this._openAppPage(aPage, aMessage);
       }
     }, this);
   },
 
   registerPage: function registerPage(aType, aPageURI, aManifestURI) {
     if (!aPageURI || !aManifestURI) {
       throw Cr.NS_ERROR_INVALID_ARG;
     }
 
+    let pageURL = aPageURI.spec;
+    let manifestURL = aManifestURI.spec;
+
+    // Don't register duplicates for this tuple.
+    let page = this._findPage(aType, pageURL, manifestURL);
+    if (page) {
+      debug("Ignoring duplicate registration of " +
+            [aType, pageURL, manifestURL]);
+      return;
+    }
+
     this._pages.push({ type: aType,
-                       uri: aPageURI.spec,
-                       manifest: aManifestURI.spec,
+                       uri: pageURL,
+                       manifest: manifestURL,
                        pendingMessages: [] });
   },
 
   _findTargetIndex: function _findTargetIndex(aTargets, aTarget) {
     if (!aTargets || !aTarget) {
       return -1;
     }
     for (let index = 0; index < aTargets.length; ++index) {
@@ -356,23 +363,17 @@ SystemMessageInternal.prototype = {
       }
       case "SystemMessageManager:GetPendingMessages":
       {
         debug("received SystemMessageManager:GetPendingMessages " + msg.type +
           " for " + msg.uri + " @ " + msg.manifest);
 
         // This is a sync call used to return the pending messages for a page.
         // Find the right page to get its corresponding pending messages.
-        let page = null;
-        this._pages.some(function(aPage) {
-          if (this._isPageMatched(aPage, msg.type, msg.uri, msg.manifest)) {
-            page = aPage;
-          }
-          return page !== null;
-        }, this);
+        let page = this._findPage(msg.type, msg.uri, msg.manifest);
         if (!page) {
           return;
         }
 
         // Return the |msg| of each pending message (drop the |msgID|).
         let pendingMessages = [];
         page.pendingMessages.forEach(function(aMessage) {
           pendingMessages.push(aMessage.msg);
@@ -393,50 +394,41 @@ SystemMessageInternal.prototype = {
       }
       case "SystemMessageManager:HasPendingMessages":
       {
         debug("received SystemMessageManager:HasPendingMessages " + msg.type +
           " for " + msg.uri + " @ " + msg.manifest);
 
         // This is a sync call used to return if a page has pending messages.
         // Find the right page to get its corresponding pending messages.
-        let page = null;
-        this._pages.some(function(aPage) {
-          if (this._isPageMatched(aPage, msg.type, msg.uri, msg.manifest)) {
-            page = aPage;
-          }
-          return page !== null;
-        }, this);
+        let page = this._findPage(msg.type, msg.uri, msg.manifest);
         if (!page) {
           return false;
         }
 
         return page.pendingMessages.length != 0;
         break;
       }
       case "SystemMessageManager:Message:Return:OK":
       {
         debug("received SystemMessageManager:Message:Return:OK " + msg.type +
           " for " + msg.uri + " @ " + msg.manifest);
 
         // We need to clean up the pending message since the app has already
         // received it, thus avoiding the re-lanunched app handling it again.
-        this._pages.forEach(function(aPage) {
-          if (!this._isPageMatched(aPage, msg.type, msg.uri, msg.manifest)) {
-            return;
-          }
-
-          let pendingMessages = aPage.pendingMessages;
+        let page = this._findPage(msg.type, msg.uri, msg.manifest);
+        if (page) {
+          let pendingMessages = page.pendingMessages;
           for (let i = 0; i < pendingMessages.length; i++) {
             if (pendingMessages[i].msgID === msg.msgID) {
               pendingMessages.splice(i, 1);
               break;
             }
           }
-        }, this);
+        }
         break;
       }
       case "SystemMessageManager:HandleMessagesDone":
       {
         debug("received SystemMessageManager:HandleMessagesDone " + msg.type +
           " with " + msg.handledCount + " for " + msg.uri + " @ " + msg.manifest);
 
         // A page has finished handling some of its system messages, so we try