Bug 1627533 - Create a request context id for each BrowsingContext. r=nika,dragana,necko-reviewers
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 21 May 2020 03:38:14 +0000
changeset 531375 a2531f6f6505caa071a482fc35f2f8bd70fbc6f0
parent 531374 d10fc18b00d38c0c355797b8cce07d6d49dbfe23
child 531376 80377f949b46616cec510584a405131a49bdcf94
push id37438
push userabutkovits@mozilla.com
push dateThu, 21 May 2020 09:36:57 +0000
treeherdermozilla-central@2d00a1a6495c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnika, dragana, necko-reviewers
bugs1627533
milestone78.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 1627533 - Create a request context id for each BrowsingContext. r=nika,dragana,necko-reviewers Previously we created a new request context id for each LoadGroup, which meant we didn't have a constant value across process switches. The next patch uses this request context id when creating a new LoadGroup for an nsDocShell, so that all docshell/loadgroups for a BrowsingContext share the same id. Differential Revision: https://phabricator.services.mozilla.com/D75884
docshell/base/BrowsingContext.cpp
docshell/base/BrowsingContext.h
netwerk/base/RequestContextService.cpp
netwerk/base/nsLoadGroup.cpp
--- a/docshell/base/BrowsingContext.cpp
+++ b/docshell/base/BrowsingContext.cpp
@@ -24,16 +24,17 @@
 #include "mozilla/dom/StructuredCloneTags.h"
 #include "mozilla/dom/UserActivationIPCUtils.h"
 #include "mozilla/dom/WindowBinding.h"
 #include "mozilla/dom/WindowGlobalChild.h"
 #include "mozilla/dom/WindowGlobalParent.h"
 #include "mozilla/dom/WindowProxyHolder.h"
 #include "mozilla/dom/SyncedContextInlines.h"
 #include "mozilla/net/DocumentLoadListener.h"
+#include "mozilla/net/RequestContextService.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/Components.h"
 #include "mozilla/HashTable.h"
 #include "mozilla/Logging.h"
 #include "mozilla/ResultExtensions.h"
 #include "mozilla/Services.h"
@@ -300,16 +301,26 @@ already_AddRefed<BrowsingContext> Browsi
 
   context->mFields.SetWithoutSyncing<IDX_OrientationLock>(
       mozilla::hal::eScreenOrientation_None);
 
   const bool useGlobalHistory =
       inherit ? inherit->GetUseGlobalHistory() : false;
   context->mFields.SetWithoutSyncing<IDX_UseGlobalHistory>(useGlobalHistory);
 
+  nsCOMPtr<nsIRequestContextService> rcsvc =
+      net::RequestContextService::GetOrCreate();
+  if (rcsvc) {
+    nsCOMPtr<nsIRequestContext> requestContext;
+    nsresult rv = rcsvc->NewRequestContext(getter_AddRefs(requestContext));
+    if (NS_SUCCEEDED(rv) && requestContext) {
+      context->mRequestContextId = requestContext->GetID();
+    }
+  }
+
   return context.forget();
 }
 
 already_AddRefed<BrowsingContext> BrowsingContext::CreateIndependent(
     Type aType) {
   RefPtr<BrowsingContext> bc(
       CreateDetached(nullptr, nullptr, EmptyString(), aType));
   bc->mWindowless = bc->IsContent();
@@ -364,16 +375,17 @@ void BrowsingContext::CreateFromIPC(Brow
     context->InitSessionHistory();
   }
 
   // NOTE: Call through the `Set` methods for these values to ensure that any
   // relevant process-local state is also updated.
   context->SetOriginAttributes(aInit.mOriginAttributes);
   context->SetRemoteTabs(aInit.mUseRemoteTabs);
   context->SetRemoteSubframes(aInit.mUseRemoteSubframes);
+  context->mRequestContextId = aInit.mRequestContextId;
   // NOTE: Private browsing ID is set by `SetOriginAttributes`.
 
   Register(context);
 
   context->Attach(/* aFromIPC */ true, aOriginProcess);
 }
 
 BrowsingContext::BrowsingContext(WindowContext* aParentWindow,
@@ -547,16 +559,22 @@ void BrowsingContext::Attach(bool aFromI
 void BrowsingContext::Detach(bool aFromIPC) {
   MOZ_DIAGNOSTIC_ASSERT(mEverAttached);
 
   MOZ_LOG(GetLog(), LogLevel::Debug,
           ("%s: Detaching 0x%08" PRIx64 " from 0x%08" PRIx64,
            XRE_IsParentProcess() ? "Parent" : "Child", Id(),
            GetParent() ? GetParent()->Id() : 0));
 
+  nsCOMPtr<nsIRequestContextService> rcsvc =
+      net::RequestContextService::GetOrCreate();
+  if (rcsvc) {
+    rcsvc->RemoveRequestContext(GetRequestContextId());
+  }
+
   // This will only ever be null if the cycle-collector has unlinked us. Don't
   // try to detach ourselves in that case.
   if (NS_WARN_IF(!mGroup)) {
     return;
   }
 
   if (mParentWindow) {
     mParentWindow->RemoveChildBrowsingContext(this);
@@ -1835,16 +1853,17 @@ BrowsingContext::IPCInitializer Browsing
   IPCInitializer init;
   init.mId = Id();
   init.mParentId = mParentWindow ? mParentWindow->Id() : 0;
   init.mWindowless = mWindowless;
   init.mUseRemoteTabs = mUseRemoteTabs;
   init.mUseRemoteSubframes = mUseRemoteSubframes;
   init.mOriginAttributes = mOriginAttributes;
   init.mHasSessionHistory = mChildSessionHistory != nullptr;
+  init.mRequestContextId = mRequestContextId;
   init.mFields = mFields.Fields();
   return init;
 }
 
 already_AddRefed<WindowContext> BrowsingContext::IPCInitializer::GetParent() {
   RefPtr<WindowContext> parent;
   if (mParentId != 0) {
     parent = WindowContext::GetById(mParentId);
--- a/docshell/base/BrowsingContext.h
+++ b/docshell/base/BrowsingContext.h
@@ -254,16 +254,18 @@ class BrowsingContext : public nsILoadCo
   void Embed();
 
   // Get the outer window object for this BrowsingContext if it is in-process
   // and still has a docshell, or null otherwise.
   nsPIDOMWindowOuter* GetDOMWindow() const {
     return mDocShell ? mDocShell->GetWindow() : nullptr;
   }
 
+  uint64_t GetRequestContextId() const { return mRequestContextId; }
+
   // Detach the current BrowsingContext from its parent, in both the
   // child and the parent process.
   void Detach(bool aFromIPC = false);
 
   // Prepare this BrowsingContext to leave the current process.
   void PrepareForProcessChange();
 
   // Triggers a load in the process which currently owns this BrowsingContext.
@@ -559,25 +561,27 @@ class BrowsingContext : public nsILoadCo
 
     uint64_t GetOpenerId() const { return mozilla::Get<IDX_OpenerId>(mFields); }
 
     bool mWindowless = false;
     bool mUseRemoteTabs = false;
     bool mUseRemoteSubframes = false;
     bool mHasSessionHistory = false;
     OriginAttributes mOriginAttributes;
+    uint64_t mRequestContextId = 0;
 
     FieldTuple mFields;
 
     bool operator==(const IPCInitializer& aOther) const {
       return mId == aOther.mId && mParentId == aOther.mParentId &&
              mWindowless == aOther.mWindowless &&
              mUseRemoteTabs == aOther.mUseRemoteTabs &&
              mUseRemoteSubframes == aOther.mUseRemoteSubframes &&
              mOriginAttributes == aOther.mOriginAttributes &&
+             mRequestContextId == aOther.mRequestContextId &&
              mFields == aOther.mFields;
     }
   };
 
   // Create an IPCInitializer object for this BrowsingContext.
   IPCInitializer GetIPCInitializer();
 
   // Create a BrowsingContext object from over IPC.
@@ -799,16 +803,20 @@ class BrowsingContext : public nsILoadCo
   // objectMoved hook and clear it from its finalize hook.
   JS::Heap<JSObject*> mWindowProxy;
   LocationProxy mLocation;
 
   // OriginAttributes for this BrowsingContext. May not be changed after this
   // BrowsingContext is attached.
   OriginAttributes mOriginAttributes;
 
+  // The network request context id, representing the nsIRequestContext
+  // associated with this BrowsingContext, and LoadGroups created for it.
+  uint64_t mRequestContextId = 0;
+
   // Determines if private browsing should be used. May not be changed after
   // this BrowsingContext is attached. This field matches mOriginAttributes in
   // content Browsing Contexts. Currently treated as a binary value: 1 - in
   // private mode, 0 - not private mode.
   uint32_t mPrivateBrowsingId;
 
   // True if Attach() has been called on this BrowsingContext already.
   bool mEverAttached : 1;
--- a/netwerk/base/RequestContextService.cpp
+++ b/netwerk/base/RequestContextService.cpp
@@ -471,16 +471,20 @@ void RequestContextService::Shutdown() {
   sShutdown = true;
 }
 
 /* static */
 already_AddRefed<nsIRequestContextService>
 RequestContextService::GetOrCreate() {
   MOZ_ASSERT(NS_IsMainThread());
 
+  if (sShutdown) {
+    return nullptr;
+  }
+
   RefPtr<RequestContextService> svc;
   if (gSingleton) {
     svc = gSingleton;
   } else {
     svc = new RequestContextService();
     nsresult rv = svc->Init();
     NS_ENSURE_SUCCESS(rv, nullptr);
     gSingleton = svc;
@@ -542,20 +546,16 @@ RequestContextService::NewRequestContext
   mTable.Put(rcID, newSC);
   newSC.swap(*rc);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 RequestContextService::RemoveRequestContext(const uint64_t rcID) {
-  if (IsNeckoChild() && gNeckoChild) {
-    gNeckoChild->SendRemoveRequestContext(rcID);
-  }
-
   MOZ_ASSERT(NS_IsMainThread());
   mTable.Remove(rcID);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 RequestContextService::Observe(nsISupports* subject, const char* topic,
                                const char16_t* data_unicode) {
--- a/netwerk/base/nsLoadGroup.cpp
+++ b/netwerk/base/nsLoadGroup.cpp
@@ -102,16 +102,19 @@ nsLoadGroup::nsLoadGroup()
 nsLoadGroup::~nsLoadGroup() {
   DebugOnly<nsresult> rv = Cancel(NS_BINDING_ABORTED);
   NS_ASSERTION(NS_SUCCEEDED(rv), "Cancel failed");
 
   mDefaultLoadRequest = nullptr;
 
   if (mRequestContext) {
     mRequestContextService->RemoveRequestContext(mRequestContext->GetID());
+    if (IsNeckoChild() && gNeckoChild) {
+      gNeckoChild->SendRemoveRequestContext(mRequestContext->GetID());
+    }
   }
 
   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
   if (os) {
     Unused << os->RemoveObserver(this, "last-pb-context-exited");
   }
 
   LOG(("LOADGROUP [%p]: Destroyed.\n", this));