Bug 1395938 - Cancel RequestContext::RequestContext on shutdown r=michal
authorValentin Gosu <valentin.gosu@gmail.com>
Sun, 03 Sep 2017 13:12:30 +0300
changeset 428266 d54673f840a41ed3382c44c379deb33c813066f9
parent 428265 7bb00f5e01201380ca9d9afd68db1738f39c9380
child 428267 4ef718d6269b63f825176056428f8d507a9357f8
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmichal
bugs1395938
milestone57.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 1395938 - Cancel RequestContext::RequestContext on shutdown r=michal This patch calls CancelTailPendingRequests(NS_ERROR_ABORT) for every RequestContext at shutdown, then prevents the creation of any more RequestContexts. MozReview-Commit-ID: BbJDL7Np8HW
netwerk/base/RequestContextService.cpp
--- a/netwerk/base/RequestContextService.cpp
+++ b/netwerk/base/RequestContextService.cpp
@@ -22,16 +22,19 @@
 
 namespace mozilla {
 namespace net {
 
 LazyLogModule gRequestContextLog("RequestContext");
 #undef LOG
 #define LOG(args) MOZ_LOG(gRequestContextLog, LogLevel::Info, args)
 
+// This is used to prevent adding tail pending requests after shutdown
+static bool sShutdown = false;
+
 // nsIRequestContext
 class RequestContext final : public nsIRequestContext
                            , public nsITimerCallback
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIREQUESTCONTEXT
   NS_DECL_NSITIMERCALLBACK
@@ -330,16 +333,20 @@ RequestContext::IsContextTailBlocked(nsI
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   LOG(("RequestContext::IsContextTailBlocked this=%p, request=%p, queued=%zu",
        this, aRequest, mTailQueue.Length()));
 
   *aBlocked = false;
 
+  if (sShutdown) {
+    return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
+  }
+
   if (mUntailAt.IsNull()) {
     LOG(("  untail time passed"));
     return NS_OK;
   }
 
   if (mAfterDOMContentLoaded && !mNonTailRequests) {
     LOG(("  after DOMContentLoaded and no untailed requests"));
     return NS_OK;
@@ -454,17 +461,23 @@ RequestContextService::Init()
 
   return NS_OK;
 }
 
 void
 RequestContextService::Shutdown()
 {
   MOZ_ASSERT(NS_IsMainThread());
+  // We need to do this to prevent the requests from being scheduled after
+  // shutdown.
+  for (auto iter = mTable.Iter(); !iter.Done(); iter.Next()) {
+    iter.Data()->CancelTailPendingRequests(NS_ERROR_ABORT);
+  }
   mTable.Clear();
+  sShutdown = true;
 }
 
 /* static */ nsresult
 RequestContextService::Create(nsISupports *aOuter, const nsIID& aIID, void **aResult)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (aOuter != nullptr) {
     return NS_ERROR_NO_AGGREGATION;
@@ -479,16 +492,20 @@ RequestContextService::Create(nsISupport
 
 NS_IMETHODIMP
 RequestContextService::GetRequestContext(const uint64_t rcID, nsIRequestContext **rc)
 {
   MOZ_ASSERT(NS_IsMainThread());
   NS_ENSURE_ARG_POINTER(rc);
   *rc = nullptr;
 
+  if (sShutdown) {
+    return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
+  }
+
   if (!mTable.Get(rcID, rc)) {
     nsCOMPtr<nsIRequestContext> newSC = new RequestContext(rcID);
     mTable.Put(rcID, newSC);
     newSC.swap(*rc);
   }
 
   return NS_OK;
 }
@@ -509,16 +526,20 @@ RequestContextService::GetRequestContext
 
 NS_IMETHODIMP
 RequestContextService::NewRequestContext(nsIRequestContext **rc)
 {
   MOZ_ASSERT(NS_IsMainThread());
   NS_ENSURE_ARG_POINTER(rc);
   *rc = nullptr;
 
+  if (sShutdown) {
+    return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
+  }
+
   uint64_t rcID = ((static_cast<uint64_t>(mRCIDNamespace) << 32) & 0xFFFFFFFF00000000LL) | mNextRCID++;
 
   nsCOMPtr<nsIRequestContext> newSC = new RequestContext(rcID);
   mTable.Put(rcID, newSC);
   newSC.swap(*rc);
 
   return NS_OK;
 }