Bug 1336240 - Remove observer in PendingLookup and nsChannelClassifier draft
authorThomas Nguyen <tnguyen@mozilla.com>
Fri, 24 Feb 2017 10:14:07 +0800
changeset 488933 6253966d3620b089b97d9669271220760afdec8a
parent 488932 7d50c8e3086d4cd1f05895b3dceac091f8825f1a
child 546880 67aa5f7fdc4d695e1ae5c715e560ab02dbfc7fd5
push id46689
push usertnguyen@mozilla.com
push dateFri, 24 Feb 2017 02:15:17 +0000
bugs1336240
milestone54.0a1
Bug 1336240 - Remove observer in PendingLookup and nsChannelClassifier MozReview-Commit-ID: EBQpQzESVZP
netwerk/base/nsChannelClassifier.cpp
netwerk/base/nsChannelClassifier.h
toolkit/components/downloads/ApplicationReputation.cpp
--- a/netwerk/base/nsChannelClassifier.cpp
+++ b/netwerk/base/nsChannelClassifier.cpp
@@ -431,21 +431,17 @@ nsChannelClassifier::StartInternal()
         LOG(("nsChannelClassifier[%p]: suspended channel %p",
              this, mChannel.get()));
     } else {
         LOG(("nsChannelClassifier[%p]: not expecting callback", this));
         return NS_ERROR_FAILURE;
     }
 
     // Add an observer for shutdown
-    nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
-    if (!observerService)
-      return NS_ERROR_FAILURE;
-
-    observerService->AddObserver(this, "profile-change-net-teardown", false);
+    AddShutdownObserver();
     return NS_OK;
 }
 
 bool
 nsChannelClassifier::IsHostnameWhitelisted(nsIURI *aUri,
                                            const nsACString &aWhitelisted)
 {
   nsAutoCString host;
@@ -812,34 +808,55 @@ nsChannelClassifier::OnClassifyComplete(
         mChannel->Cancel(aErrorCode);
       }
       LOG(("nsChannelClassifier[%p]: resuming channel %p from "
            "OnClassifyComplete", this, mChannel.get()));
       mChannel->Resume();
     }
 
     mChannel = nullptr;
+    RemoveShutdownObserver();
 
     return NS_OK;
 }
 
+void
+nsChannelClassifier::AddShutdownObserver()
+{
+  nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
+  if (observerService) {
+    observerService->AddObserver(this, "profile-change-net-teardown", false);
+  }
+}
+
+void
+nsChannelClassifier::RemoveShutdownObserver()
+{
+  nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
+  if (observerService) {
+    observerService->RemoveObserver(this, "profile-change-net-teardown");
+  }
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // nsIObserver implementation
 NS_IMETHODIMP
 nsChannelClassifier::Observe(nsISupports *aSubject, const char *aTopic,
                              const char16_t *aData)
 {
   if (!strcmp(aTopic, "profile-change-net-teardown")) {
     // If we aren't getting a callback for any reason, make sure
     // we resume the channel.
 
     if (mChannel && mSuspendedChannel) {
       mSuspendedChannel = false;
       mChannel->Cancel(NS_ERROR_ABORT);
       mChannel->Resume();
     }
+
+    RemoveShutdownObserver();
   }
 
   return NS_OK;
 }
 
 } // namespace net
 } // namespace mozilla
--- a/netwerk/base/nsChannelClassifier.h
+++ b/netwerk/base/nsChannelClassifier.h
@@ -55,16 +55,18 @@ private:
     bool IsHostnameWhitelisted(nsIURI *aUri, const nsACString &aWhitelisted);
     // Checks that the channel was loaded by the URI currently loaded in aDoc
     static bool SameLoadingURI(nsIDocument *aDoc, nsIChannel *aChannel);
 
     nsresult ShouldEnableTrackingProtectionInternal(nsIChannel *aChannel,
                                                     bool *result);
 
     bool AddonMayLoad(nsIChannel *aChannel, nsIURI *aUri);
+    void AddShutdownObserver();
+    void RemoveShutdownObserver();
 public:
     // If we are blocking content, update the corresponding flag in the respective
     // docshell and call nsISecurityEventSink::onSecurityChange.
     static nsresult SetBlockedContent(nsIChannel *channel,
                                       nsresult aErrorCode,
                                       const nsACString& aList,
                                       const nsACString& aProvider,
                                       const nsACString& aPrefix);
--- a/toolkit/components/downloads/ApplicationReputation.cpp
+++ b/toolkit/components/downloads/ApplicationReputation.cpp
@@ -48,16 +48,17 @@
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsThreadUtils.h"
 #include "nsXPCOMStrings.h"
 
 #include "nsIContentPolicy.h"
 #include "nsILoadInfo.h"
 #include "nsContentUtils.h"
+#include "nsWeakReference.h"
 
 using mozilla::ArrayLength;
 using mozilla::BasePrincipal;
 using mozilla::OriginAttributes;
 using mozilla::Preferences;
 using mozilla::TimeStamp;
 using mozilla::Telemetry::Accumulate;
 using safe_browsing::ClientDownloadRequest;
@@ -89,17 +90,18 @@ mozilla::LazyLogModule ApplicationReputa
 class PendingDBLookup;
 
 // A single use class private to ApplicationReputationService encapsulating an
 // nsIApplicationReputationQuery and an nsIApplicationReputationCallback. Once
 // created by ApplicationReputationService, it is guaranteed to call mCallback.
 // This class is private to ApplicationReputationService.
 class PendingLookup final : public nsIStreamListener,
                             public nsITimerCallback,
-                            public nsIObserver
+                            public nsIObserver,
+                            public nsSupportsWeakReference
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSITIMERCALLBACK
   NS_DECL_NSIOBSERVER
 
@@ -369,17 +371,18 @@ PendingDBLookup::HandleEvent(const nsACS
     Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_LOCAL, NO_LIST);
   }
   return mPendingLookup->LookupNext();
 }
 
 NS_IMPL_ISUPPORTS(PendingLookup,
                   nsIStreamListener,
                   nsIRequestObserver,
-                  nsIObserver)
+                  nsIObserver,
+                  nsISupportsWeakReference)
 
 PendingLookup::PendingLookup(nsIApplicationReputationQuery* aQuery,
                              nsIApplicationReputationCallback* aCallback) :
   mBlocklistCount(0),
   mAllowlistCount(0),
   mQuery(aQuery),
   mCallback(aCallback)
 {
@@ -1538,11 +1541,11 @@ nsresult ApplicationReputationService::Q
 
   // Add an observer for shutdown
   nsCOMPtr<nsIObserverService> observerService =
     mozilla::services::GetObserverService();
   if (!observerService) {
     return NS_ERROR_FAILURE;
   }
 
-  observerService->AddObserver(lookup, "quit-application", false);
+  observerService->AddObserver(lookup, "quit-application", true);
   return lookup->StartLookup();
 }