Bug 1242755 - Move nsHttpConnectionMgr->Shutdown back to nsHttpHandler. r=mcmanus, a=lizzard
authorDragana Damjanovic dd.mozilla@gmail.com
Thu, 04 Feb 2016 04:14:00 +0100
changeset 318960 0b1f0e02a992bf2f3f81f7fb98674baad327b4e3
parent 318959 b07639a98ceee1afb934fdbc694d3f5eefa96bbd
child 318961 917763c36a6e9a66dc5270e4514e07251967e5d4
push id1079
push userjlund@mozilla.com
push dateFri, 15 Apr 2016 21:02:33 +0000
treeherdermozilla-release@575fbf6786d5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcmanus, lizzard
bugs1242755
milestone46.0a2
Bug 1242755 - Move nsHttpConnectionMgr->Shutdown back to nsHttpHandler. r=mcmanus, a=lizzard
netwerk/base/nsIOService.cpp
netwerk/base/nsIOService.h
netwerk/protocol/http/nsHttpHandler.cpp
--- a/netwerk/base/nsIOService.cpp
+++ b/netwerk/base/nsIOService.cpp
@@ -46,31 +46,29 @@
 #include "mozilla/LoadInfo.h"
 #include "mozilla/net/NeckoCommon.h"
 #include "mozilla/Services.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/net/DNS.h"
 #include "CaptivePortalService.h"
 #include "ReferrerPolicy.h"
 #include "nsContentSecurityManager.h"
-#include "nsHttpHandler.h"
 
 #ifdef MOZ_WIDGET_GONK
 #include "nsINetworkManager.h"
 #include "nsINetworkInterface.h"
 #endif
 
 #if defined(XP_WIN)
 #include "nsNativeConnectionHelper.h"
 #endif
 
 using namespace mozilla;
 using mozilla::net::IsNeckoChild;
 using mozilla::net::CaptivePortalService;
-using mozilla::net::gHttpHandler;
 
 #define PORT_PREF_PREFIX           "network.security.ports."
 #define PORT_PREF(x)               PORT_PREF_PREFIX x
 #define AUTODIAL_PREF              "network.autodial-helper.enabled"
 #define MANAGE_OFFLINE_STATUS_PREF "network.manage-offline-status"
 #define OFFLINE_MIRRORS_CONNECTIVITY "network.offline-mirrors-connectivity"
 
 // Nb: these have been misnomers since bug 715770 removed the buffer cache.
@@ -177,16 +175,17 @@ nsIOService::nsIOService()
     : mOffline(true)
     , mOfflineForProfileChange(false)
     , mManageLinkStatus(false)
     , mConnectivity(true)
     , mOfflineMirrorsConnectivity(true)
     , mSettingOffline(false)
     , mSetOfflineValue(false)
     , mShutdown(false)
+    , mHttpHandlerAlreadyShutingDown(false)
     , mNetworkLinkServiceInitialized(false)
     , mChannelEventSinks(NS_CHANNEL_EVENT_SINK_CATEGORY)
     , mAutoDialEnabled(false)
     , mNetworkNotifyChanged(true)
     , mPreviousWifiState(-1)
     , mLastOfflineStateChange(PR_IntervalNow())
     , mLastConnectivityChange(PR_IntervalNow())
     , mLastNetworkLinkChange(PR_IntervalNow())
@@ -1402,33 +1401,42 @@ nsIOService::NotifyWakeup()
 
     if (mCaptivePortalService) {
         mCaptivePortalService->RecheckCaptivePortal();
     }
 
     return NS_OK;
 }
 
+void
+nsIOService::SetHttpHandlerAlreadyShutingDown()
+{
+    if (!mShutdown && !mOfflineForProfileChange) {
+        mNetTearingDownStarted = PR_IntervalNow();
+        mHttpHandlerAlreadyShutingDown = true;
+    }
+}
+
 // nsIObserver interface
 NS_IMETHODIMP
 nsIOService::Observe(nsISupports *subject,
                      const char *topic,
                      const char16_t *data)
 {
     if (!strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
         nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(subject);
         if (prefBranch)
             PrefsChanged(prefBranch, NS_ConvertUTF16toUTF8(data).get());
     } else if (!strcmp(topic, kProfileChangeNetTeardownTopic)) {
+        if (!mHttpHandlerAlreadyShutingDown) {
+          mNetTearingDownStarted = PR_IntervalNow();
+        }
+        mHttpHandlerAlreadyShutingDown = false;
         if (!mOffline) {
             mOfflineForProfileChange = true;
-            mNetTearingDownStarted = PR_IntervalNow();
-            if (gHttpHandler) {
-                gHttpHandler->ShutdownConnectionManager();
-            }
             SetOffline(true);
         }
     } else if (!strcmp(topic, kProfileChangeNetRestoreTopic)) {
         if (mOfflineForProfileChange) {
             mOfflineForProfileChange = false;
             SetOffline(false);
         }
     } else if (!strcmp(topic, kProfileDoChange)) { 
@@ -1444,22 +1452,22 @@ nsIOService::Observe(nsISupports *subjec
             GetPrefBranch(getter_AddRefs(prefBranch));
             PrefsChanged(prefBranch, MANAGE_OFFLINE_STATUS_PREF);
         }
     } else if (!strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
         // Remember we passed XPCOM shutdown notification to prevent any
         // changes of the offline status from now. We must not allow going
         // online after this point.
         mShutdown = true;
-        if (!mOfflineForProfileChange) {
+
+        if (!mHttpHandlerAlreadyShutingDown && !mOfflineForProfileChange) {
           mNetTearingDownStarted = PR_IntervalNow();
         }
-        if (gHttpHandler) {
-            gHttpHandler->ShutdownConnectionManager();
-        }
+        mHttpHandlerAlreadyShutingDown = false;
+
         SetOffline(true);
 
         if (mCaptivePortalService) {
             static_cast<CaptivePortalService*>(mCaptivePortalService.get())->Stop();
             mCaptivePortalService = nullptr;
         }
 
         // Break circular reference.
--- a/netwerk/base/nsIOService.h
+++ b/netwerk/base/nsIOService.h
@@ -79,18 +79,27 @@ public:
     nsresult AsyncOnChannelRedirect(nsIChannel* oldChan, nsIChannel* newChan,
                                     uint32_t flags,
                                     nsAsyncRedirectVerifyHelper *helper);
 
     bool IsOffline() { return mOffline; }
     PRIntervalTime LastOfflineStateChange() { return mLastOfflineStateChange; }
     PRIntervalTime LastConnectivityChange() { return mLastConnectivityChange; }
     PRIntervalTime LastNetworkLinkChange() { return mLastNetworkLinkChange; }
-    bool IsNetTearingDown() { return mShutdown || mOfflineForProfileChange; }
+    bool IsNetTearingDown() { return mShutdown || mOfflineForProfileChange ||
+                                     mHttpHandlerAlreadyShutingDown; }
     PRIntervalTime NetTearingDownStarted() { return mNetTearingDownStarted; }
+
+    // nsHttpHandler is going to call this function to inform nsIOService that network
+    // is in process of tearing down. Moving nsHttpConnectionMgr::Shutdown to nsIOService
+    // caused problems (bug 1242755) so we doing it in this way.
+    // As soon as nsIOService gets notification that it is shutdown it is going to
+    // reset mHttpHandlerAlreadyShutingDown.
+    void SetHttpHandlerAlreadyShutingDown();
+
     bool IsLinkUp();
 
     // Should only be called from NeckoChild. Use SetAppOffline instead.
     void SetAppOfflineInternal(uint32_t appId, int32_t status);
 
 private:
     // These shouldn't be called directly:
     // - construct using GetInstance
@@ -147,16 +156,17 @@ private:
     bool                                 mOfflineMirrorsConnectivity;
 
     // Used to handle SetOffline() reentrancy.  See the comment in
     // SetOffline() for more details.
     bool                                 mSettingOffline;
     bool                                 mSetOfflineValue;
 
     mozilla::Atomic<bool, mozilla::Relaxed> mShutdown;
+    mozilla::Atomic<bool, mozilla::Relaxed> mHttpHandlerAlreadyShutingDown;
 
     nsCOMPtr<nsPISocketTransportService> mSocketTransportService;
     nsCOMPtr<nsPIDNSService>             mDNSService;
     nsCOMPtr<nsIProtocolProxyService2>   mProxyService;
     nsCOMPtr<nsICaptivePortalService>    mCaptivePortalService;
     nsCOMPtr<nsINetworkLinkService>      mNetworkLinkService;
     bool                                 mNetworkLinkServiceInitialized;
 
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -48,16 +48,17 @@
 #include "nsIMemoryReporter.h"
 #include "nsIParentalControlsService.h"
 #include "nsPIDOMWindow.h"
 #include "nsINetworkLinkService.h"
 #include "nsHttpChannelAuthProvider.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsSocketTransportService2.h"
+#include "nsIOService.h"
 
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "mozilla/Telemetry.h"
 
 #if defined(XP_UNIX)
 #include <sys/utsname.h>
 #endif
@@ -2055,16 +2056,21 @@ nsHttpHandler::Observe(nsISupports *subj
         mHandlerActive = false;
 
         // clear cache of all authentication credentials.
         mAuthCache.ClearAll();
         mPrivateAuthCache.ClearAll();
         if (mWifiTickler)
             mWifiTickler->Cancel();
 
+        // Inform nsIOService that network is tearing down.
+        gIOService->SetHttpHandlerAlreadyShutingDown();
+
+        ShutdownConnectionManager();
+
         // need to reset the session start time since cache validation may
         // depend on this value.
         mSessionStartTime = NowInSeconds();
 
         if (!mDoNotTrackEnabled) {
             Telemetry::Accumulate(Telemetry::DNT_USAGE, 2);
         } else {
             Telemetry::Accumulate(Telemetry::DNT_USAGE, 1);