Bug 802395: fix parse error caused by messages being sent when the port isn't yet fully initialized, r=gavin
authorShane Caraveo <scaraveo@mozilla.com>
Tue, 16 Oct 2012 16:47:42 -0700
changeset 110761 77deb50b07e19baa0fea0db55e54b355b8a5ff11
parent 110760 2f193f44cb99ff2275a14e04f50f0b22f5018c53
child 110762 0d10847ab5481533d6055923ef3597147be7db82
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersgavin
bugs802395
milestone19.0a1
Bug 802395: fix parse error caused by messages being sent when the port isn't yet fully initialized, r=gavin
toolkit/components/social/MessagePortBase.jsm
toolkit/components/social/test/browser/browser_workerAPI.js
toolkit/components/social/test/browser/worker_social.js
--- a/toolkit/components/social/MessagePortBase.jsm
+++ b/toolkit/components/social/MessagePortBase.jsm
@@ -39,20 +39,20 @@ AbstractPort.prototype = {
   },
 
   _onmessage: function fw_AbstractPort_onmessage(data) {
     // See comments in postMessage below - we work around a cloning
     // issue by using JSON for these messages.
     // Further, we allow the workers to override exactly how the JSON parsing
     // is done - we try and do such parsing in the client window so things
     // like prototype overrides on Array work as expected.
-    data = this._JSONParse(data);
     if (!this._handler) {
       this._pendingMessagesIncoming.push(data);
     } else {
+      data = this._JSONParse(data);
       try {
         this._handler({
           data: data,
           __exposedProps__: {
             data: 'r'
           }
         });
       } catch (ex) {
--- a/toolkit/components/social/test/browser/browser_workerAPI.js
+++ b/toolkit/components/social/test/browser/browser_workerAPI.js
@@ -109,36 +109,39 @@ let tests = {
     Cu.import("resource://gre/modules/FrameWorker.jsm", fw);
 
     // get a real handle to the worker so we can watch the unload event
     // we watch for the unload of the worker to know it is infact being
     // unloaded, after that if we get worker.connected we know that
     // the worker was loaded again and ports reconnected
     let reloading = false;
     let worker = fw.getFrameWorkerHandle(provider.workerURL, undefined, "testWorkerReload");
-    let win = worker._worker.frame.contentWindow;
+    let frame =  worker._worker.frame;
+    let win = frame.contentWindow;
+    let port = provider.getWorkerPort();
     win.addEventListener("unload", function workerUnload(e) {
       win.removeEventListener("unload", workerUnload);
       ok(true, "worker unload event has fired");
-      reloading = true;
+      is(port._pendingMessagesOutgoing.length, 0, "port has no pending outgoing message");
     });
-    let port = provider.getWorkerPort();
+    frame.addEventListener("DOMWindowCreated", function workerLoaded(e) {
+      frame.removeEventListener("DOMWindowCreated", workerLoaded);
+      // send a message which should end up pending
+      port.postMessage({topic: "test-pending-msg"});
+      ok(port._pendingMessagesOutgoing.length > 0, "port has pending outgoing message");
+    });
     ok(port, "provider has a port");
     port.onmessage = function (e) {
       let topic = e.data.topic;
       switch (topic) {
         case "test-initialization-complete":
           // tell the worker to send the reload msg
           port.postMessage({topic: "test-reload-init"});
           break;
-        case "worker.connected":
-          // we'll get this message from the worker on every load of the worker,
-          // so we need to ignore it unless we have requested the reload.
-          if (reloading) {
-            ok(true, "worker reloaded and testPort was reconnected");
-            next();
-          }
+        case "test-pending-response":
+          ok(true, "worker reloaded and testPort was reconnected");
+          next();
           break;
       }
     }
     port.postMessage({topic: "test-initialization"});
   }
 };
--- a/toolkit/components/social/test/browser/worker_social.js
+++ b/toolkit/components/social/test/browser/worker_social.js
@@ -20,16 +20,19 @@ onconnect = function(e) {
         break;
       case "test-initialization":
         testerPort = port;
         port.postMessage({topic: "test-initialization-complete"});
         break;
       case "test-profile":
         apiPort.postMessage({topic: "social.user-profile", data: data});
         break;
+      case "test-pending-msg":
+        port.postMessage({topic: "test-pending-response"})
+        break;
       case "test-ambient":
         apiPort.postMessage({topic: "social.ambient-notification", data: data});
         break;
       case "test.cookies-get":
         apiPort.postMessage({topic: "social.cookies-get"});
         break;
       case "social.cookies-get-response":
         testerPort.postMessage({topic: "test.cookies-get-response", data: data});