Bug 1193605 - Part 3: do not stop non-started service; r=mcmanus
authorLiang-Heng Chen <xeonchen@mozilla.com>
Tue, 25 Aug 2015 07:15:00 +0200
changeset 294721 bb221f207c1aa908dd1de4d1d6325d5f7c7e9346
parent 294720 fa04b5843674a98e2dfdf5243a15997d01d6e2d1
child 294722 62e37d61a0961d6700518fa35c091dce7873f87c
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcmanus
bugs1193605
milestone43.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 1193605 - Part 3: do not stop non-started service; r=mcmanus
netwerk/dns/mdns/libmdns/nsDNSServiceDiscovery.js
--- a/netwerk/dns/mdns/libmdns/nsDNSServiceDiscovery.js
+++ b/netwerk/dns/mdns/libmdns/nsDNSServiceDiscovery.js
@@ -12,18 +12,25 @@ const DNSSERVICEDISCOVERY_CID = Componen
 const DNSSERVICEDISCOVERY_CONTRACT_ID = "@mozilla.org/toolkit/components/mdnsresponder/dns-sd;1";
 const DNSSERVICEINFO_CONTRACT_ID = "@mozilla.org/toolkit/components/mdnsresponder/dns-info;1";
 
 function log(aMsg) {
   dump("-*- nsDNSServiceDiscovery.js : " + aMsg + "\n");
 }
 
 // Helper class to transform return objects to correct type.
-function ListenerWrapper(aListener) {
+function ListenerWrapper(aListener, aMdns) {
   this.listener = aListener;
+  this.mdns = aMdns;
+
+  this.discoveryStarting = false;
+  this.stopDiscovery = false;
+
+  this.registrationStarting = false;
+  this.stopRegistration = false;
 }
 
 ListenerWrapper.prototype = {
   // Helper function for transforming an Object into nsIDNSServiceInfo.
   makeServiceInfo: function (aServiceInfo) {
     let serviceInfo = Cc[DNSSERVICEINFO_CONTRACT_ID].createInstance(Ci.nsIDNSServiceInfo);
 
     for (let name of ['host', 'port', 'serviceName', 'serviceType']) {
@@ -34,88 +41,117 @@ ListenerWrapper.prototype = {
       }
     }
 
     return serviceInfo;
   },
 
   /* transparent types */
   onDiscoveryStarted: function(aServiceType) {
+    this.discoveryStarting = false;
     this.listener.onDiscoveryStarted(aServiceType);
+
+    if (this.stopDiscovery) {
+      this.mdns.stopDiscovery(aServiceType, this);
+    }
   },
   onDiscoveryStopped: function(aServiceType) {
     this.listener.onDiscoveryStopped(aServiceType);
   },
   onStartDiscoveryFailed: function(aServiceType, aErrorCode) {
-    this.listener.onStartDiscoveryFailed(aServiceType);
+    log('onStartDiscoveryFailed: ' + aServiceType + ' (' + aErrorCode + ')');
+    this.discoveryStarting = false;
+    this.stopDiscovery = true;
+    this.listener.onStartDiscoveryFailed(aServiceType, aErrorCode);
   },
   onStopDiscoveryFailed: function(aServiceType, aErrorCode) {
-    this.listener.onStopDiscoveryFailed(aServiceType);
+    log('onStopDiscoveryFailed: ' + aServiceType + ' (' + aErrorCode + ')');
+    this.listener.onStopDiscoveryFailed(aServiceType, aErrorCode);
   },
 
   /* transform types */
   onServiceFound: function(aServiceInfo) {
     this.listener.onServiceFound(this.makeServiceInfo(aServiceInfo));
   },
   onServiceLost: function(aServiceInfo) {
     this.listener.onServiceLost(this.makeServiceInfo(aServiceInfo));
   },
   onServiceRegistered: function(aServiceInfo) {
+    this.registrationStarting = false;
     this.listener.onServiceRegistered(this.makeServiceInfo(aServiceInfo));
+
+    if (this.stopRegistration) {
+      this.mdns.unregisterService(aServiceInfo, this);
+    }
   },
   onServiceUnregistered: function(aServiceInfo) {
     this.listener.onServiceUnregistered(this.makeServiceInfo(aServiceInfo));
   },
   onServiceResolved: function(aServiceInfo) {
     this.listener.onServiceResolved(this.makeServiceInfo(aServiceInfo));
   },
 
   onRegistrationFailed: function(aServiceInfo, aErrorCode) {
+    log('onRegistrationFailed: (' + aErrorCode + ')');
+    this.registrationStarting = false;
+    this.stopRegistration = true;
     this.listener.onRegistrationFailed(this.makeServiceInfo(aServiceInfo), aErrorCode);
   },
   onUnregistrationFailed: function(aServiceInfo, aErrorCode) {
+    log('onUnregistrationFailed: (' + aErrorCode + ')');
     this.listener.onUnregistrationFailed(this.makeServiceInfo(aServiceInfo), aErrorCode);
   },
   onResolveFailed: function(aServiceInfo, aErrorCode) {
+    log('onResolveFailed: (' + aErrorCode + ')');
     this.listener.onResolveFailed(this.makeServiceInfo(aServiceInfo), aErrorCode);
   }
 };
 
 function nsDNSServiceDiscovery() {
   log("nsDNSServiceDiscovery");
   this.mdns = new MulticastDNS();
 }
 
 nsDNSServiceDiscovery.prototype = {
   classID: DNSSERVICEDISCOVERY_CID,
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference, Ci.nsIDNSServiceDiscovery]),
 
   startDiscovery: function(aServiceType, aListener) {
     log("startDiscovery");
-    let listener = new ListenerWrapper(aListener);
+    let listener = new ListenerWrapper(aListener, this.mdns);
+    listener.discoveryStarting = true;
     this.mdns.startDiscovery(aServiceType, listener);
 
     return {
       QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
       cancel: (function() {
-        this.mdns.stopDiscovery(aServiceType, listener);
-      }).bind(this)
+        if (this.discoveryStarting || this.stopDiscovery) {
+          this.stopDiscovery = true;
+          return;
+        }
+        this.mdns.stopDiscovery(aServiceType, this);
+      }).bind(listener)
     };
   },
 
   registerService: function(aServiceInfo, aListener) {
     log("registerService");
-    let listener = new ListenerWrapper(aListener);
+    let listener = new ListenerWrapper(aListener, this.mdns);
+    listener.registrationStarting = true;
     this.mdns.registerService(aServiceInfo, listener);
 
     return {
       QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
       cancel: (function() {
-        this.mdns.unregisterService(aServiceInfo, listener);
-      }).bind(this)
+        if (this.registrationStarting || this.stopRegistration) {
+          this.stopRegistration = true;
+          return;
+        }
+        this.mdns.unregisterService(aServiceInfo, this);
+      }).bind(listener)
     };
   },
 
   resolveService: function(aServiceInfo, aListener) {
     log("resolveService");
     this.mdns.resolveService(aServiceInfo, new ListenerWrapper(aListener));
   }
 };