Bug 1297554 - Perform a gNeckoParent-ectomy r?mcmanus,billm draft
authorNicholas Hurley <hurley@todesschaf.org>
Wed, 21 Sep 2016 12:21:00 -0700
changeset 417998 a9fd99a411315240c69ba420e9eff7fd9644461d
parent 417997 247628524d995b725cc78062fed02190acb0da0f
child 532227 e3f6284708c590d40625ad7a811614c581598c41
push id30555
push userbmo:hurley@todesschaf.org
push dateTue, 27 Sep 2016 13:56:11 +0000
reviewersmcmanus, billm
bugs1297554
milestone52.0a1
Bug 1297554 - Perform a gNeckoParent-ectomy r?mcmanus,billm MozReview-Commit-ID: 7WQE8MhWlYr
netwerk/base/Predictor.cpp
netwerk/ipc/NeckoParent.cpp
netwerk/ipc/NeckoParent.h
netwerk/protocol/http/nsHttpHandler.cpp
--- a/netwerk/base/Predictor.cpp
+++ b/netwerk/base/Predictor.cpp
@@ -43,16 +43,18 @@
 #include "mozilla/net/NeckoCommon.h"
 #include "mozilla/net/NeckoParent.h"
 
 #include "LoadContextInfo.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "SerializedLoadContext.h"
 #include "mozilla/net/NeckoChild.h"
 
+#include "mozilla/dom/ContentParent.h"
+
 using namespace mozilla;
 
 namespace mozilla {
 namespace net {
 
 Predictor *Predictor::sSelf = nullptr;
 
 static LazyLogModule gPredictorLog("NetworkPredictor");
@@ -2222,65 +2224,92 @@ PredictorLearnRedirect(nsIURI *targetURI
 
 /**
  * Call through to the child's verifier (only during tests)
  */
 NS_IMETHODIMP
 Predictor::OnPredictPrefetch(nsIURI *aURI, uint32_t httpStatus)
 {
   if (IsNeckoChild()) {
-    MOZ_DIAGNOSTIC_ASSERT(mChildVerifier);
-    return mChildVerifier->OnPredictPrefetch(aURI, httpStatus);
+    if (mChildVerifier) {
+      // Ideally, we'd assert here. But since we're slowly moving towards a
+      // world where we have multiple child processes, and only one child process
+      // will be likely to have a verifier, we have to play it safer.
+      return mChildVerifier->OnPredictPrefetch(aURI, httpStatus);
+    }
+    return NS_OK;
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(gNeckoParent);
-
   ipc::URIParams serURI;
   SerializeURI(aURI, serURI);
 
-  if (!gNeckoParent->SendPredOnPredictPrefetch(serURI, httpStatus)) {
-    return NS_ERROR_NOT_AVAILABLE;
+  for (auto* cp : ContentParent::AllProcesses(ContentParent::eLive)) {
+    PNeckoParent* neckoParent = SingleManagedOrNull(cp->ManagedPNeckoParent());
+    if (!neckoParent) {
+      continue;
+    }
+    if (!neckoParent->SendPredOnPredictPrefetch(serURI, httpStatus)) {
+      return NS_ERROR_NOT_AVAILABLE;
+    }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 Predictor::OnPredictPreconnect(nsIURI *aURI) {
   if (IsNeckoChild()) {
-    MOZ_DIAGNOSTIC_ASSERT(mChildVerifier);
-    return mChildVerifier->OnPredictPreconnect(aURI);
+    if (mChildVerifier) {
+      // Ideally, we'd assert here. But since we're slowly moving towards a
+      // world where we have multiple child processes, and only one child process
+      // will be likely to have a verifier, we have to play it safer.
+      return mChildVerifier->OnPredictPreconnect(aURI);
+    }
+    return NS_OK;
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(gNeckoParent);
-
   ipc::URIParams serURI;
   SerializeURI(aURI, serURI);
 
-  if (!gNeckoParent->SendPredOnPredictPreconnect(serURI)) {
-    return NS_ERROR_NOT_AVAILABLE;
+  for (auto* cp : ContentParent::AllProcesses(ContentParent::eLive)) {
+    PNeckoParent* neckoParent = SingleManagedOrNull(cp->ManagedPNeckoParent());
+    if (!neckoParent) {
+      continue;
+    }
+    if (!neckoParent->SendPredOnPredictPreconnect(serURI)) {
+      return NS_ERROR_NOT_AVAILABLE;
+    }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 Predictor::OnPredictDNS(nsIURI *aURI) {
   if (IsNeckoChild()) {
-    MOZ_DIAGNOSTIC_ASSERT(mChildVerifier);
-    return mChildVerifier->OnPredictDNS(aURI);
+    if (mChildVerifier) {
+      // Ideally, we'd assert here. But since we're slowly moving towards a
+      // world where we have multiple child processes, and only one child process
+      // will be likely to have a verifier, we have to play it safer.
+      return mChildVerifier->OnPredictDNS(aURI);
+    }
+    return NS_OK;
   }
 
-  MOZ_DIAGNOSTIC_ASSERT(gNeckoParent);
-
   ipc::URIParams serURI;
   SerializeURI(aURI, serURI);
 
-  if (!gNeckoParent->SendPredOnPredictDNS(serURI)) {
-    return NS_ERROR_NOT_AVAILABLE;
+  for (auto* cp : ContentParent::AllProcesses(ContentParent::eLive)) {
+    PNeckoParent* neckoParent = SingleManagedOrNull(cp->ManagedPNeckoParent());
+    if (!neckoParent) {
+      continue;
+    }
+    if (!neckoParent->SendPredOnPredictDNS(serURI)) {
+      return NS_ERROR_NOT_AVAILABLE;
+    }
   }
 
   return NS_OK;
 }
 
 // Predictor::PrefetchListener
 // nsISupports
 NS_IMPL_ISUPPORTS(Predictor::PrefetchListener,
--- a/netwerk/ipc/NeckoParent.cpp
+++ b/netwerk/ipc/NeckoParent.cpp
@@ -58,43 +58,39 @@ using mozilla::net::PTCPServerSocketPare
 using mozilla::dom::TCPServerSocketParent;
 using mozilla::net::PUDPSocketParent;
 using mozilla::dom::UDPSocketParent;
 using IPC::SerializedLoadContext;
 
 namespace mozilla {
 namespace net {
 
-PNeckoParent *gNeckoParent = nullptr;
-
 // C++ file contents
 NeckoParent::NeckoParent()
 {
   // Init HTTP protocol handler now since we need atomTable up and running very
   // early (IPDL argument handling for PHttpChannel constructor needs it) so
   // normal init (during 1st Http channel request) isn't early enough.
   nsCOMPtr<nsIProtocolHandler> proto =
     do_GetService("@mozilla.org/network/protocol;1?name=http");
 
   mObserver = new OfflineObserver(this);
-  gNeckoParent = this;
 
   // only register once--we will have multiple NeckoParents if there are
   // multiple child processes.
   static bool registeredBool = false;
   if (!registeredBool) {
     Preferences::AddBoolVarCache(&NeckoCommonInternal::gSecurityDisabled,
                                  "network.disable.ipc.security");
     registeredBool = true;
   }
 }
 
 NeckoParent::~NeckoParent()
 {
-  gNeckoParent = nullptr;
   if (mObserver) {
     mObserver->RemoveObserver();
   }
 }
 
 static PBOverrideStatus
 PBOverrideStatusFromLoadContext(const SerializedLoadContext& aSerialized)
 {
--- a/netwerk/ipc/NeckoParent.h
+++ b/netwerk/ipc/NeckoParent.h
@@ -230,17 +230,12 @@ protected:
   virtual bool RecvPredReset() override;
 
   virtual bool RecvRemoveRequestContext(const nsCString& rcid) override;
 
 private:
   RefPtr<OfflineObserver> mObserver;
 };
 
-/**
- * Reference to the PNecko Parent protocol.
- */
-extern PNeckoParent *gNeckoParent;
-
 } // namespace net
 } // namespace mozilla
 
 #endif // mozilla_net_NeckoParent_h
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -57,16 +57,18 @@
 
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/net/NeckoParent.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Unused.h"
 #include "mozilla/BasePrincipal.h"
 
+#include "mozilla/dom/ContentParent.h"
+
 #if defined(XP_UNIX)
 #include <sys/utsname.h>
 #endif
 
 #if defined(XP_WIN)
 #include <windows.h>
 #endif
 
@@ -2219,18 +2221,24 @@ nsHttpHandler::SpeculativeConnectInterna
 
     MOZ_ASSERT(NS_IsMainThread());
     nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
     if (mDebugObservations && obsService) {
         // this is basically used for test coverage of an otherwise 'hintable'
         // feature
         obsService->NotifyObservers(nullptr, "speculative-connect-request",
                                     nullptr);
-        if (!IsNeckoChild() && gNeckoParent) {
-            Unused << gNeckoParent->SendSpeculativeConnectRequest();
+        if (!IsNeckoChild()) {
+            for (auto* cp : dom::ContentParent::AllProcesses(dom::ContentParent::eLive)) {
+                PNeckoParent* neckoParent = SingleManagedOrNull(cp->ManagedPNeckoParent());
+                if (!neckoParent) {
+                    continue;
+                }
+                Unused << neckoParent->SendSpeculativeConnectRequest();
+            }
         }
     }
 
     nsISiteSecurityService* sss = gHttpHandler->GetSSService();
     bool isStsHost = false;
     if (!sss)
         return NS_OK;