Bug 1596409 - P6: Add a pref for using socket process for network r=dragana
authorKershaw Chang <kershaw@mozilla.com>
Tue, 03 Dec 2019 13:46:04 +0000
changeset 505085 103b1e697c6fe4fc360e9abfc2e24fe8d14d3c52
parent 505084 628adc2416c935a5b2860911cc658a2bd8fdda6e
child 505086 ec2d5fef8d14d262525c7eecd7ec8d124bbd40c6
push id102139
push userkjang@mozilla.com
push dateTue, 03 Dec 2019 13:47:51 +0000
treeherderautoland@103b1e697c6f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdragana
bugs1596409
milestone73.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 1596409 - P6: Add a pref for using socket process for network r=dragana Differential Revision: https://phabricator.services.mozilla.com/D54174
modules/libpref/init/all.js
netwerk/base/nsIOService.cpp
netwerk/base/nsIOService.h
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpHandler.cpp
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1519,16 +1519,21 @@ pref("network.sts.poll_busy_wait_period_
 pref("network.sts.max_time_for_pr_close_during_shutdown", 5000);
 
 // When the polling socket pair we use to wake poll() up on demand doesn't
 // get signalled (is not readable) within this timeout, we try to repair it.
 // This timeout can be disabled by setting this pref to 0.
 // The value is expected in seconds.
 pref("network.sts.pollable_event_timeout", 6);
 
+// Perform all network access on the socket process.
+// The pref requires "network.sts.socket_process.enable" to be true.
+// Changing these prefs requires a restart.
+pref("network.http.network_access_on_socket_process.enabled", false);
+
 // Enable/disable sni encryption.
 pref("network.security.esni.enabled", false);
 
 // 2147483647 == PR_INT32_MAX == ~2 GB
 pref("network.websocket.max-message-size", 2147483647);
 
 // Should we automatically follow http 3xx redirects during handshake
 pref("network.websocket.auto-follow-http-redirects", false);
--- a/netwerk/base/nsIOService.cpp
+++ b/netwerk/base/nsIOService.cpp
@@ -444,16 +444,32 @@ void nsIOService::DestroySocketProcess()
   mSocketProcess->Shutdown();
   mSocketProcess = nullptr;
 }
 
 bool nsIOService::SocketProcessReady() {
   return mSocketProcess && mSocketProcess->IsConnected();
 }
 
+static bool sUseSocketProcess = false;
+static bool sUseSocketProcessChecked = false;
+
+bool nsIOService::UseSocketProcess() {
+  if (sUseSocketProcessChecked) {
+    return sUseSocketProcess;
+  }
+
+  sUseSocketProcessChecked = true;
+  if (Preferences::GetBool("network.process.enabled")) {
+    sUseSocketProcess = Preferences::GetBool(
+        "network.http.network_access_on_socket_process.enabled", true);
+  }
+  return sUseSocketProcess;
+}
+
 // static
 void nsIOService::NotifySocketProcessPrefsChanged(const char* aName,
                                                   void* aSelf) {
   static_cast<nsIOService*>(aSelf)->NotifySocketProcessPrefsChanged(aName);
 }
 
 void nsIOService::NotifySocketProcessPrefsChanged(const char* aName) {
   MOZ_ASSERT(NS_IsMainThread());
--- a/netwerk/base/nsIOService.h
+++ b/netwerk/base/nsIOService.h
@@ -114,16 +114,17 @@ class nsIOService final : public nsIIOSe
   // Used to trigger a recheck of the captive portal status
   nsresult RecheckCaptivePortal();
 
   void OnProcessLaunchComplete(SocketProcessHost* aHost, bool aSucceeded);
   void OnProcessUnexpectedShutdown(SocketProcessHost* aHost);
   bool SocketProcessReady();
   static void NotifySocketProcessPrefsChanged(const char* aName, void* aSelf);
   void NotifySocketProcessPrefsChanged(const char* aName);
+  bool UseSocketProcess();
 
   bool IsSocketProcessLaunchComplete();
 
   // Call func immediately if socket process is launched completely. Otherwise,
   // |func| will be queued and then executed in the *main thread* once socket
   // process is launced.
   void CallOrWaitForSocketProcess(const std::function<void()>& aFunc);
 
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -112,16 +112,17 @@
 #include "mozilla/extensions/StreamFilterParent.h"
 #include "mozilla/net/Predictor.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/NullPrincipal.h"
 #include "CacheControlParser.h"
 #include "nsMixedContentBlocker.h"
 #include "CacheStorageService.h"
 #include "HttpChannelParent.h"
+#include "HttpTransactionParent.h"
 #include "ParentChannelListener.h"
 #include "InterceptedHttpChannel.h"
 #include "nsIBufferedStreams.h"
 #include "nsIFileStreams.h"
 #include "nsIMIMEInputStream.h"
 #include "nsIMultiplexInputStream.h"
 #include "../../cache2/CacheFileUtils.h"
 #include "../../cache2/CacheHashUtils.h"
@@ -131,16 +132,17 @@
 #include "mozilla/net/AsyncUrlChannelClassifier.h"
 #include "mozilla/net/CookieSettings.h"
 #include "mozilla/net/NeckoChannelParams.h"
 #include "mozilla/net/UrlClassifierFeatureFactory.h"
 #include "nsIWebNavigation.h"
 #include "HttpTrafficAnalyzer.h"
 #include "mozilla/dom/CanonicalBrowsingContext.h"
 #include "mozilla/dom/WindowGlobalParent.h"
+#include "mozilla/net/SocketProcessParent.h"
 #include "js/Conversions.h"
 
 #ifdef MOZ_TASK_TRACER
 #  include "GeckoTaskTracer.h"
 #endif
 
 #ifdef MOZ_GECKO_PROFILER
 #  include "ProfilerMarkerPayload.h"
@@ -1246,19 +1248,36 @@ nsresult nsHttpChannel::SetupTransaction
   }
 
   // create wrapper for this channel's notification callbacks
   nsCOMPtr<nsIInterfaceRequestor> callbacks;
   NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
                                          getter_AddRefs(callbacks));
 
   // create the transaction object
-  mTransaction = new nsHttpTransaction();
-  LOG1(("nsHttpChannel %p created nsHttpTransaction %p\n", this,
-        mTransaction.get()));
+  if (gIOService->UseSocketProcess()) {
+    MOZ_ASSERT(gIOService->SocketProcessReady(),
+               "Socket process should be ready.");
+
+    RefPtr<HttpTransactionParent> transParent = new HttpTransactionParent();
+    LOG1(("nsHttpChannel %p created HttpTransactionParent %p\n", this,
+          transParent.get()));
+
+    SocketProcessParent* socketProcess = SocketProcessParent::GetSingleton();
+    if (socketProcess) {
+      Unused << socketProcess->SendPHttpTransactionConstructor(transParent);
+    }
+
+    mTransaction = transParent;
+  } else {
+    mTransaction = new nsHttpTransaction();
+    LOG1(("nsHttpChannel %p created nsHttpTransaction %p\n", this,
+          mTransaction.get()));
+  }
+
   mTransaction->SetTransactionObserver(mTransactionObserver);
   mTransactionObserver = nullptr;
 
   // See bug #466080. Transfer LOAD_ANONYMOUS flag to socket-layer.
   if (mLoadFlags & LOAD_ANONYMOUS) mCaps |= NS_HTTP_LOAD_ANONYMOUS;
 
   if (mTimingEnabled) mCaps |= NS_HTTP_TIMING_ENABLED;
 
@@ -6456,16 +6475,24 @@ nsHttpChannel::AsyncOpen(nsIStreamListen
     gHttpHandler->OnOpeningRequest(this);
   }
 
   mIsPending = true;
   mWasOpened = true;
 
   mListener = listener;
 
+  if (gIOService->UseSocketProcess() &&
+      !gIOService->IsSocketProcessLaunchComplete()) {
+    RefPtr<nsHttpChannel> self = this;
+    gIOService->CallOrWaitForSocketProcess(
+        [self]() { self->AsyncOpenFinal(TimeStamp::Now()); });
+    return NS_OK;
+  }
+
   // PauseTask/DelayHttpChannel queuing
   if (!DelayHttpChannelQueue::AttemptQueueChannel(this)) {
     // If fuzzyfox is disabled; or adding to the queue failed, the channel must
     // continue.
     AsyncOpenFinal(TimeStamp::Now());
   }
 
   return NS_OK;
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -56,19 +56,21 @@
 #include "nsSocketTransportService2.h"
 #include "nsIOService.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIXULRuntime.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "nsRFPService.h"
 #include "rust-helper/src/helper.h"
 
+#include "mozilla/net/HttpConnectionMgrParent.h"
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/net/NeckoParent.h"
 #include "mozilla/net/RequestContextService.h"
+#include "mozilla/net/SocketProcessParent.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Unused.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/LazyIdleThread.h"
 
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/Navigator.h"
@@ -584,29 +586,45 @@ void nsHttpHandler::MakeNewRequestTokenB
 }
 
 nsresult nsHttpHandler::InitConnectionMgr() {
   // Init ConnectionManager only on parent!
   if (IsNeckoChild()) {
     return NS_OK;
   }
 
-  nsresult rv;
+  if (mConnMgr) {
+    return NS_OK;
+  }
 
-  if (!mConnMgr) {
+  if (gIOService->UseSocketProcess() && XRE_IsParentProcess()) {
+    if (!gIOService->SocketProcessReady()) {
+      gIOService->CallOrWaitForSocketProcess(
+          []() { Unused << gHttpHandler->InitConnectionMgr(); });
+      return NS_OK;
+    }
+
+    RefPtr<HttpConnectionMgrParent> connMgr = new HttpConnectionMgrParent();
+    if (!SocketProcessParent::GetSingleton()->SendPHttpConnectionMgrConstructor(
+            connMgr)) {
+      return NS_ERROR_FAILURE;
+    }
+
+    mConnMgr = connMgr;
+  } else {
+    MOZ_ASSERT(XRE_IsSocketProcess() || !gIOService->UseSocketProcess());
     mConnMgr = new nsHttpConnectionMgr();
   }
 
-  rv = mConnMgr->Init(
+  return mConnMgr->Init(
       mMaxUrgentExcessiveConns, mMaxConnections,
       mMaxPersistentConnectionsPerServer, mMaxPersistentConnectionsPerProxy,
       mMaxRequestDelay, mThrottleEnabled, mThrottleVersion, mThrottleSuspendFor,
       mThrottleResumeFor, mThrottleReadLimit, mThrottleReadInterval,
       mThrottleHoldTime, mThrottleMaxTime, mBeConservativeForProxy);
-  return rv;
 }
 
 nsresult nsHttpHandler::AddStandardRequestHeaders(
     nsHttpRequestHead* request, bool isSecure,
     nsContentPolicyType aContentPolicyType) {
   nsresult rv;
 
   // Add the "User-Agent" header
@@ -2692,36 +2710,34 @@ HttpTrafficAnalyzer* nsHttpHandler::GetH
 }
 
 bool nsHttpHandler::IsHttp3VersionSupportedHex(const nsACString& version) {
   return version.LowerCaseEqualsLiteral(kHttp3VersionHEX);
 }
 
 nsresult nsHttpHandler::InitiateTransaction(HttpTransactionShell* aTrans,
                                             int32_t aPriority) {
-  return mConnMgr->AddTransaction(aTrans->AsHttpTransaction(), aPriority);
+  return mConnMgr->AddTransaction(aTrans, aPriority);
 }
 nsresult nsHttpHandler::InitiateTransactionWithStickyConn(
     HttpTransactionShell* aTrans, int32_t aPriority,
     HttpTransactionShell* aTransWithStickyConn) {
-  return mConnMgr->AddTransactionWithStickyConn(
-      aTrans->AsHttpTransaction(), aPriority,
-      aTransWithStickyConn->AsHttpTransaction());
+  return mConnMgr->AddTransactionWithStickyConn(aTrans, aPriority,
+                                                aTransWithStickyConn);
 }
 
 nsresult nsHttpHandler::RescheduleTransaction(HttpTransactionShell* trans,
                                               int32_t priority) {
-  return mConnMgr->RescheduleTransaction(trans->AsHttpTransaction(), priority);
+  return mConnMgr->RescheduleTransaction(trans, priority);
 }
 
 void nsHttpHandler::UpdateClassOfServiceOnTransaction(
     HttpTransactionShell* trans, uint32_t classOfService) {
-  mConnMgr->UpdateClassOfServiceOnTransaction(trans->AsHttpTransaction(),
-                                              classOfService);
+  mConnMgr->UpdateClassOfServiceOnTransaction(trans, classOfService);
 }
 
 nsresult nsHttpHandler::CancelTransaction(HttpTransactionShell* trans,
                                           nsresult reason) {
-  return mConnMgr->CancelTransaction(trans->AsHttpTransaction(), reason);
+  return mConnMgr->CancelTransaction(trans, reason);
 }
 
 }  // namespace net
 }  // namespace mozilla