Bug 1020024 - fix data channel connecting race conditions. r=jib
authorNils Ohlmeier [:drno] <drno@ohlmeier.org>
Wed, 02 Jul 2014 18:08:00 +0200
changeset 192079 35e4a142417cade44c2aab85946a141e43a99c53
parent 192078 559eb932b214aded765040e620b7b52791c791a1
child 192080 0ddb94bb72c802ff2df3ea80d74abe1cd4c76580
child 192163 af2c7776626540dc8eed65c78d7eda056a2c3018
push id27073
push usercbook@mozilla.com
push dateThu, 03 Jul 2014 11:47:13 +0000
treeherdermozilla-central@0ddb94bb72c8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjib
bugs1020024
milestone33.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 1020024 - fix data channel connecting race conditions. r=jib
dom/media/tests/mochitest/pc.js
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -1114,48 +1114,64 @@ DataChannelTest.prototype = Object.creat
      *
      * @param {PeerConnectionWrapper} peer
      *        The peer connection wrapper to run the command on
      * @param {Function} onSuccess
      *        Callback when the creation was successful
      */
     value : function DCT_waitForInitialDataChannel(peer, onSuccess, onFailure) {
       var dcConnectionTimeout = null;
+      var dcOpened = false;
 
       function dataChannelConnected(channel) {
-        clearTimeout(dcConnectionTimeout);
-        is(channel.readyState, "open", peer + " dataChannels[0] switched to state: 'open'");
-        onSuccess();
-      }
-
-      if (peer.dataChannels.length >= 1) {
-        if (peer.dataChannels[0].readyState === "open") {
-          is(peer.dataChannels[0].readyState, "open", peer + " dataChannels[0] is already in state: 'open'");
+        // in case the switch statement below had called onSuccess already we
+        // don't want to call it again
+        if (!dcOpened) {
+          clearTimeout(dcConnectionTimeout);
+          is(channel.readyState, "open", peer + " dataChannels[0] switched to state: 'open'");
+          dcOpened = true;
           onSuccess();
-          return;
-        } else {
-          is(peer.dataChannels[0].readyState, "connecting", peer + " dataChannels[0] is in state: 'connecting'");
         }
-      } else {
-        info(peer + "'s dataChannels[] is empty");
       }
 
       // TODO: drno: convert dataChannels into an object and make
       //             registerDataChannelOpenEvent a generic function
       if (peer == this.pcLocal) {
         peer.dataChannels[0].onopen = dataChannelConnected;
       } else {
         peer.registerDataChannelOpenEvents(dataChannelConnected);
       }
 
-      if (onFailure) {
-        dcConnectionTimeout = setTimeout(function () {
-          info(peer + " timed out while waiting for dataChannels[0] to connect");
-          onFailure();
-        }, 60000);
+      if (peer.dataChannels.length >= 1) {
+        // snapshot of the live value as it might change during test execution
+        const readyState = peer.dataChannels[0].readyState;
+        switch (readyState) {
+          case "open": {
+            is(readyState, "open", peer + " dataChannels[0] is already in state: 'open'");
+            dcOpened = true;
+            onSuccess();
+            break;
+          }
+          case "connecting": {
+            is(readyState, "connecting", peer + " dataChannels[0] is in state: 'connecting'");
+            if (onFailure) {
+              dcConnectionTimeout = setTimeout(function () {
+                is(peer.dataChannels[0].readyState, "open", peer + " timed out while waiting for dataChannels[0] to open");
+                onFailure();
+              }, 60000);
+            }
+            break;
+          }
+          default: {
+            ok(false, "dataChannels[0] is in unexpected state " + readyState);
+            if (onFailure) {
+              onFailure()
+            }
+          }
+        }
       }
     }
   }
 
 });
 
 /**
  * This class acts as a wrapper around a DataChannel instance.