Bug 1275464 - Part 2. Move socket transport service thread shutdown to xpcom-shutdown-threads. r=dragana
authorAndrew Osmond <aosmond@mozilla.com>
Mon, 19 Sep 2016 13:29:59 -0400
changeset 315859 f451982cae7cd667dea82640196cd6942beef235
parent 315858 738bab069e736293e8f159cc560a35f05209d8b0
child 315860 14d41b959f3a21fb40c49fa66dc1c7b23642afe8
push id20634
push usercbook@mozilla.com
push dateFri, 30 Sep 2016 10:10:13 +0000
treeherderfx-team@afe79b010d13 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdragana
bugs1275464
milestone52.0a1
Bug 1275464 - Part 2. Move socket transport service thread shutdown to xpcom-shutdown-threads. r=dragana
netwerk/base/nsIOService.cpp
netwerk/base/nsPISocketTransportService.idl
netwerk/base/nsSocketTransportService2.cpp
netwerk/base/nsSocketTransportService2.h
netwerk/standalone/nsNetModuleStandalone.cpp
--- a/netwerk/base/nsIOService.cpp
+++ b/netwerk/base/nsIOService.cpp
@@ -1100,17 +1100,17 @@ nsIOService::SetOffline(bool offline)
     if ((mShutdown || mOfflineForProfileChange) && mOffline) {
         // be sure to try and shutdown both (even if the first fails)...
         // shutdown dns service first, because it has callbacks for socket transport
         if (mDNSService) {
             DebugOnly<nsresult> rv = mDNSService->Shutdown();
             NS_ASSERTION(NS_SUCCEEDED(rv), "DNS service shutdown failed");
         }
         if (mSocketTransportService) {
-            DebugOnly<nsresult> rv = mSocketTransportService->Shutdown();
+            DebugOnly<nsresult> rv = mSocketTransportService->Shutdown(mShutdown);
             NS_ASSERTION(NS_SUCCEEDED(rv), "socket transport service shutdown failed");
         }
     }
 
     mSettingOffline = false;
 
     return NS_OK;
 }
--- a/netwerk/base/nsPISocketTransportService.idl
+++ b/netwerk/base/nsPISocketTransportService.idl
@@ -13,17 +13,17 @@
 [scriptable, uuid(18f73bf1-b35b-4b7b-aa9a-11bcbdbc389c)]
 
 interface nsPISocketTransportService : nsIRoutedSocketTransportService
 {
   /**
    * init/shutdown routines.
    */
   void init();
-  void shutdown();
+  void shutdown(in bool aXpcomShutdown);
 
   /**
    * controls the TCP sender window clamp
    */
   readonly attribute long sendBufferSize;
 
   /**
    * Controls whether the socket transport service is offline.
--- a/netwerk/base/nsSocketTransportService2.cpp
+++ b/netwerk/base/nsSocketTransportService2.cpp
@@ -548,25 +548,26 @@ nsSocketTransportService::Init()
     UpdatePrefs();
 
     nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
     if (obsSvc) {
         obsSvc->AddObserver(this, "profile-initial-state", false);
         obsSvc->AddObserver(this, "last-pb-context-exited", false);
         obsSvc->AddObserver(this, NS_WIDGET_SLEEP_OBSERVER_TOPIC, true);
         obsSvc->AddObserver(this, NS_WIDGET_WAKE_OBSERVER_TOPIC, true);
+        obsSvc->AddObserver(this, "xpcom-shutdown-threads", false);
     }
 
     mInitialized = true;
     return NS_OK;
 }
 
 // called from main thread only
 NS_IMETHODIMP
-nsSocketTransportService::Shutdown()
+nsSocketTransportService::Shutdown(bool aXpcomShutdown)
 {
     SOCKET_LOG(("nsSocketTransportService::Shutdown\n"));
 
     NS_ENSURE_STATE(NS_IsMainThread());
 
     if (!mInitialized)
         return NS_OK;
 
@@ -579,16 +580,33 @@ nsSocketTransportService::Shutdown()
         // signal the socket thread to shutdown
         mShuttingDown = true;
 
         if (mPollableEvent) {
             mPollableEvent->Signal();
         }
     }
 
+    if (!aXpcomShutdown) {
+        return ShutdownThread();
+    }
+
+    return NS_OK;
+}
+
+nsresult
+nsSocketTransportService::ShutdownThread()
+{
+    SOCKET_LOG(("nsSocketTransportService::ShutdownThread\n"));
+
+    NS_ENSURE_STATE(NS_IsMainThread());
+
+    if (!mInitialized || !mShuttingDown)
+        return NS_OK;
+
     // join with thread
     mThread->Shutdown();
     {
         MutexAutoLock lock(mLock);
         // Drop our reference to mThread and make sure that any concurrent
         // readers are excluded
         mThread = nullptr;
     }
@@ -598,16 +616,17 @@ nsSocketTransportService::Shutdown()
         tmpPrefService->RemoveObserver(SEND_BUFFER_PREF, this);
 
     nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
     if (obsSvc) {
         obsSvc->RemoveObserver(this, "profile-initial-state");
         obsSvc->RemoveObserver(this, "last-pb-context-exited");
         obsSvc->RemoveObserver(this, NS_WIDGET_SLEEP_OBSERVER_TOPIC);
         obsSvc->RemoveObserver(this, NS_WIDGET_WAKE_OBSERVER_TOPIC);
+        obsSvc->RemoveObserver(this, "xpcom-shutdown-threads");
     }
 
     if (mAfterWakeUpTimer) {
         mAfterWakeUpTimer->Cancel();
         mAfterWakeUpTimer = nullptr;
     }
 
     NetworkActivityMonitor::Shutdown();
@@ -1342,16 +1361,18 @@ nsSocketTransportService::Observe(nsISup
         }
     } else if (!strcmp(topic, NS_WIDGET_WAKE_OBSERVER_TOPIC)) {
         if (mSleepPhase && !mAfterWakeUpTimer) {
             mAfterWakeUpTimer = do_CreateInstance("@mozilla.org/timer;1");
             if (mAfterWakeUpTimer) {
                 mAfterWakeUpTimer->Init(this, 2000, nsITimer::TYPE_ONE_SHOT);
             }
         }
+    } else if (!strcmp(topic, "xpcom-shutdown-threads")) {
+        ShutdownThread();
     }
 
     return NS_OK;
 }
 
 void
 nsSocketTransportService::ClosePrivateConnections()
 {
--- a/netwerk/base/nsSocketTransportService2.h
+++ b/netwerk/base/nsSocketTransportService2.h
@@ -147,16 +147,18 @@ private:
                             // indicates whether we are currently in the
                             // process of shutting down
     bool          mOffline;
     bool          mGoingOffline;
 
     // Detaches all sockets.
     void Reset(bool aGuardLocals);
 
+    nsresult ShutdownThread();
+
     //-------------------------------------------------------------------------
     // socket lists (socket thread only)
     //
     // only "active" sockets are on the poll list.  the active list is kept
     // in sync with the poll list such that:
     //
     //   mActiveList[k].mFD == mPollList[k+1].fd
     //
--- a/netwerk/standalone/nsNetModuleStandalone.cpp
+++ b/netwerk/standalone/nsNetModuleStandalone.cpp
@@ -56,17 +56,17 @@ ShutdownNetModuleStandalone()
     mozilla::DebugOnly<nsresult> rv = dns->Shutdown();
     NS_ASSERTION(NS_SUCCEEDED(rv), "DNS service shutdown failed");
   } else {
     NS_WARNING("failed to get dns service");
   }
 
   nsCOMPtr<nsPISocketTransportService> sts = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
   if (NS_SUCCEEDED(rv)) {
-    mozilla::DebugOnly<nsresult> rv = sts->Shutdown();
+    mozilla::DebugOnly<nsresult> rv = sts->Shutdown(true);
     NS_ASSERTION(NS_SUCCEEDED(rv), "Socket transport service shutdown failed");
   } else {
     NS_WARNING("failed to get socket transport service");
   }
 
   return NS_OK;
 }