Bug 1324820 - Make sure we resume the channel if there's no classifier callback draft
authorThomas Nguyen <tnguyen@mozilla.com>
Thu, 12 Jan 2017 18:07:22 +0800
changeset 460492 73aca1278cc375069b109a5f12a8cf67992d9617
parent 460419 b1c31c4a0a678194931779e0f13fba7b508eb109
child 542056 b9badef67dedf100210d8186128289d82b241bee
push id41400
push userbmo:tnguyen@mozilla.com
push dateFri, 13 Jan 2017 04:19:02 +0000
bugs1324820
milestone53.0a1
Bug 1324820 - Make sure we resume the channel if there's no classifier callback MozReview-Commit-ID: 35jBJb1Q8Rz
netwerk/base/nsChannelClassifier.cpp
netwerk/base/nsChannelClassifier.h
toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
--- a/netwerk/base/nsChannelClassifier.cpp
+++ b/netwerk/base/nsChannelClassifier.cpp
@@ -55,17 +55,18 @@ static bool sAnnotateChannelEnabled = fa
 static bool sLowerNetworkPriority = false;
 static bool sIsInited = false;
 
 #undef LOG
 #define LOG(args)     MOZ_LOG(gChannelClassifierLog, LogLevel::Debug, args)
 #define LOG_ENABLED() MOZ_LOG_TEST(gChannelClassifierLog, LogLevel::Debug)
 
 NS_IMPL_ISUPPORTS(nsChannelClassifier,
-                  nsIURIClassifierCallback)
+                  nsIURIClassifierCallback,
+                  nsIObserver)
 
 nsChannelClassifier::nsChannelClassifier(nsIChannel *aChannel)
   : mIsAllowListed(false),
     mSuspendedChannel(false),
     mChannel(aChannel),
     mTrackingProtectionEnabled(Nothing())
 {
   MOZ_ASSERT(mChannel);
@@ -406,16 +407,22 @@ nsChannelClassifier::StartInternal()
         mSuspendedChannel = true;
         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);
     return NS_OK;
 }
 
 bool
 nsChannelClassifier::IsHostnameWhitelisted(nsIURI *aUri,
                                            const nsACString &aWhitelisted)
 {
   nsAutoCString host;
@@ -759,10 +766,30 @@ nsChannelClassifier::OnClassifyComplete(
       mChannel->Resume();
     }
 
     mChannel = nullptr;
 
     return NS_OK;
 }
 
+///////////////////////////////////////////////////////////////////////////////
+// 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();
+    }
+  }
+
+  return NS_OK;
+}
+
 } // namespace net
 } // namespace mozilla
--- a/netwerk/base/nsChannelClassifier.h
+++ b/netwerk/base/nsChannelClassifier.h
@@ -12,23 +12,25 @@
 
 class nsIChannel;
 class nsIHttpChannelInternal;
 class nsIDocument;
 
 namespace mozilla {
 namespace net {
 
-class nsChannelClassifier final : public nsIURIClassifierCallback
+class nsChannelClassifier final : public nsIURIClassifierCallback,
+                                  public nsIObserver
 {
 public:
     explicit nsChannelClassifier(nsIChannel* aChannel);
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIURICLASSIFIERCALLBACK
+    NS_DECL_NSIOBSERVER
 
     // Calls nsIURIClassifier.Classify with the principal of the given channel,
     // and cancels the channel on a bad verdict.
     void Start();
     // Whether or not tracking protection should be enabled on this channel.
     nsresult ShouldEnableTrackingProtection(bool *result);
 
 private:
--- a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
@@ -165,16 +165,19 @@ nsUrlClassifierDBServiceWorker::Init(uin
 }
 
 nsresult
 nsUrlClassifierDBServiceWorker::QueueLookup(const nsACString& spec,
                                             const nsACString& tables,
                                             nsIUrlClassifierLookupCallback* callback)
 {
   MutexAutoLock lock(mPendingLookupLock);
+  if (gShuttingDownThread) {
+      return NS_ERROR_ABORT;
+  }
 
   PendingLookup* lookup = mPendingLookups.AppendElement();
   if (!lookup) return NS_ERROR_OUT_OF_MEMORY;
 
   lookup->mStartTime = TimeStamp::Now();
   lookup->mKey = spec;
   lookup->mCallback = callback;
   lookup->mTables = tables;