Bug 1097804 - Part 1, Create a library containing nsISocketTransportService and nsIDNS that can be used to support standalone WebRTC r=mcmanus
☠☠ backed out by eebb50c44389 ☠ ☠
authorRandall Barker <rbarker@mozilla.com>
Thu, 02 Apr 2015 12:13:28 -0700
changeset 237448 e1f294f7ca90d9b5faa8ca78762f08a124aff815
parent 237447 0f5799df920bfbf966217fa7a8d511a646a53725
child 237449 c7da4d4c09aa5edd5f2acdc4b35640f2fd20ac83
push id57952
push userkwierso@gmail.com
push dateFri, 03 Apr 2015 00:57:56 +0000
treeherdermozilla-inbound@948e7e255fc9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcmanus
bugs1097804
milestone40.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 1097804 - Part 1, Create a library containing nsISocketTransportService and nsIDNS that can be used to support standalone WebRTC r=mcmanus
netwerk/base/nsSocketTransportService2.cpp
netwerk/base/nsURLHelper.cpp
netwerk/dns/nsDNSService2.cpp
netwerk/moz.build
netwerk/standalone/moz.build
netwerk/standalone/nsNetModuleStandalone.cpp
netwerk/standalone/nsNetModuleStandalone.h
xpcom/components/nsComponentManager.cpp
xpcom/components/nsComponentManager.h
xpcom/libxpcomrt/XPCOMRTInit.cpp
xpcom/libxpcomrt/moz.build
--- a/netwerk/base/nsSocketTransportService2.cpp
+++ b/netwerk/base/nsSocketTransportService2.cpp
@@ -1,25 +1,28 @@
 // vim:set sw=4 sts=4 et cin:
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsSocketTransportService2.h"
+#if !defined(MOZILLA_XPCOMRT_API)
 #include "nsSocketTransport2.h"
+#include "NetworkActivityMonitor.h"
+#include "mozilla/Preferences.h"
+#endif // !defined(MOZILLA_XPCOMRT_API)
+#include "nsASocketHandler.h"
 #include "nsError.h"
 #include "prnetdb.h"
 #include "prerror.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsServiceManagerUtils.h"
-#include "NetworkActivityMonitor.h"
 #include "nsIObserverService.h"
 #include "mozilla/Services.h"
-#include "mozilla/Preferences.h"
 #include "mozilla/Likely.h"
 #include "mozilla/PublicSSL.h"
 #include "mozilla/ChaosMode.h"
 #include "mozilla/PodOperations.h"
 #include "mozilla/Telemetry.h"
 #include "nsThreadUtils.h"
 #include "nsIFile.h"
 
@@ -555,17 +558,19 @@ nsSocketTransportService::Shutdown()
         tmpPrefService->RemoveObserver(SEND_BUFFER_PREF, this);
 
     nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
     if (obsSvc) {
         obsSvc->RemoveObserver(this, "profile-initial-state");
         obsSvc->RemoveObserver(this, "last-pb-context-exited");
     }
 
+#if !defined(MOZILLA_XPCOMRT_API)
     mozilla::net::NetworkActivityMonitor::Shutdown();
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
     mInitialized = false;
     mShuttingDown = false;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -629,33 +634,42 @@ nsSocketTransportService::GetKeepalivePr
 NS_IMETHODIMP
 nsSocketTransportService::CreateTransport(const char **types,
                                           uint32_t typeCount,
                                           const nsACString &host,
                                           int32_t port,
                                           nsIProxyInfo *proxyInfo,
                                           nsISocketTransport **result)
 {
+#if defined(MOZILLA_XPCOMRT_API)
+    NS_WARNING("nsSocketTransportService::CreateTransport not implemented");
+    return NS_ERROR_NOT_IMPLEMENTED;
+#else
     NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
     NS_ENSURE_TRUE(port >= 0 && port <= 0xFFFF, NS_ERROR_ILLEGAL_VALUE);
 
     nsRefPtr<nsSocketTransport> trans = new nsSocketTransport();
     nsresult rv = trans->Init(types, typeCount, host, port, proxyInfo);
     if (NS_FAILED(rv)) {
         return rv;
     }
 
     trans.forget(result);
     return NS_OK;
+#endif // defined(MOZILLA_XPCOMRT_API)
 }
 
 NS_IMETHODIMP
 nsSocketTransportService::CreateUnixDomainTransport(nsIFile *aPath,
                                                     nsISocketTransport **result)
 {
+#if defined(MOZILLA_XPCOMRT_API)
+    NS_WARNING("nsSocketTransportService::CreateUnixDomainTransport not implemented");
+    return NS_ERROR_NOT_IMPLEMENTED;
+#else
     nsresult rv;
 
     NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
 
     nsAutoCString path;
     rv = aPath->GetNativePath(path);
     if (NS_FAILED(rv))
         return rv;
@@ -663,16 +677,17 @@ nsSocketTransportService::CreateUnixDoma
     nsRefPtr<nsSocketTransport> trans = new nsSocketTransport();
 
     rv = trans->InitWithFilename(path.get());
     if (NS_FAILED(rv))
         return rv;
 
     trans.forget(result);
     return NS_OK;
+#endif // defined(MOZILLA_XPCOMRT_API)
 }
 
 NS_IMETHODIMP
 nsSocketTransportService::GetAutodialEnabled(bool *value)
 {
     *value = mAutodialEnabled;
     return NS_OK;
 }
@@ -727,17 +742,19 @@ nsSocketTransportService::Run()
     if (IsNuwaProcess()) {
         NuwaMarkCurrentThread(nullptr, nullptr);
     }
     NS_SetIgnoreStatusOfCurrentThread();
 #endif
 
     SOCKET_LOG(("STS thread init\n"));
 
+#if !defined(MOZILLA_XPCOMRT_API)
     psm::InitializeSSLServerCertVerificationThreads();
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
     gSocketThread = PR_GetCurrentThread();
 
     // add thread event to poll list (mThreadEvent may be nullptr)
     mPollList[0].fd = mThreadEvent;
     mPollList[0].in_flags = PR_POLL_READ;
     mPollList[0].out_flags = 0;
 
@@ -896,17 +913,19 @@ nsSocketTransportService::Run()
     Reset(false);
 
     // Final pass over the event queue. This makes sure that events posted by
     // socket detach handlers get processed.
     NS_ProcessPendingEvents(thread);
 
     gSocketThread = nullptr;
 
+#if !defined(MOZILLA_XPCOMRT_API)
     psm::StopSSLServerCertVerificationThreads();
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
     SOCKET_LOG(("STS thread exit\n"));
     return NS_OK;
 }
 
 void
 nsSocketTransportService::DetachSocketWithGuard(bool aGuardLocals,
                                                 SocketContext *socketList,
@@ -1080,16 +1099,20 @@ nsSocketTransportService::DoPollIteratio
     }
 
     return NS_OK;
 }
 
 nsresult
 nsSocketTransportService::UpdatePrefs()
 {
+#if defined(MOZILLA_XPCOMRT_API)
+    NS_WARNING("nsSocketTransportService::UpdatePrefs not implemented");
+    return NS_ERROR_NOT_IMPLEMENTED;
+#else
     mSendBufferSize = 0;
     
     nsCOMPtr<nsIPrefBranch> tmpPrefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
     if (tmpPrefService) {
         int32_t bufferSize;
         nsresult rv = tmpPrefService->GetIntPref(SEND_BUFFER_PREF, &bufferSize);
         if (NS_SUCCEEDED(rv) && bufferSize > 0)
             mSendBufferSize = bufferSize;
@@ -1141,16 +1164,17 @@ nsSocketTransportService::UpdatePrefs()
         rv = tmpPrefService->GetBoolPref(TELEMETRY_PREF,
                                          &telemetryPref);
         if (NS_SUCCEEDED(rv)) {
             mTelemetryEnabledPref = telemetryPref;
         }
     }
     
     return NS_OK;
+#endif // defined(MOZILLA_XPCOMRT_API)
 }
 
 void
 nsSocketTransportService::OnKeepaliveEnabledPrefChange()
 {
     // Dispatch to socket thread if we're not executing there.
     if (PR_GetCurrentThread() != gSocketThread) {
         gSocketTransportService->Dispatch(
@@ -1185,29 +1209,31 @@ nsSocketTransportService::NotifyKeepaliv
     sock->mHandler->OnKeepaliveEnabledPrefChange(mKeepaliveEnabledPref);
 }
 
 NS_IMETHODIMP
 nsSocketTransportService::Observe(nsISupports *subject,
                                   const char *topic,
                                   const char16_t *data)
 {
+#if !defined(MOZILLA_XPCOMRT_API)
     if (!strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
         UpdatePrefs();
         return NS_OK;
     }
 
     if (!strcmp(topic, "profile-initial-state")) {
         int32_t blipInterval = Preferences::GetInt(BLIP_INTERVAL_PREF, 0);
         if (blipInterval <= 0) {
             return NS_OK;
         }
 
         return net::NetworkActivityMonitor::Init(blipInterval);
     }
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
     if (!strcmp(topic, "last-pb-context-exited")) {
         nsCOMPtr<nsIRunnable> ev =
           NS_NewRunnableMethod(this,
                                &nsSocketTransportService::ClosePrivateConnections);
         nsresult rv = Dispatch(ev, nsIEventTarget::DISPATCH_NORMAL);
         NS_ENSURE_SUCCESS(rv, rv);
     }
@@ -1231,17 +1257,19 @@ nsSocketTransportService::ClosePrivateCo
         }
     }
     for (int32_t i = mIdleCount - 1; i >= 0; --i) {
         if (mIdleList[i].mHandler->mIsPrivate) {
             DetachSocket(mIdleList, &mIdleList[i]);
         }
     }
 
+#if !defined(MOZILLA_XPCOMRT_API)
     mozilla::ClearPrivateSSLState();
+#endif // !defined(MOZILLA_XPCOMRT_API)
 }
 
 NS_IMETHODIMP
 nsSocketTransportService::GetSendBufferSize(int32_t *value)
 {
     *value = mSendBufferSize;
     return NS_OK;
 }
--- a/netwerk/base/nsURLHelper.cpp
+++ b/netwerk/base/nsURLHelper.cpp
@@ -48,18 +48,20 @@ InitGlobals()
     parser = do_GetService(NS_STDURLPARSER_CONTRACTID);
     NS_ASSERTION(parser, "failed getting 'std' url parser");
     if (parser) {
         gStdURLParser = parser.get();
         NS_ADDREF(gStdURLParser);
     }
 
     gInitialized = true;
+#if !defined(MOZILLA_XPCOMRT_API)
     Preferences::AddIntVarCache(&gMaxLength,
                                 "network.standard-url.max-length", 1048576);
+#endif
 }
 
 void
 net_ShutdownURLHelper()
 {
     if (gInitialized) {
         NS_IF_RELEASE(gNoAuthURLParser);
         NS_IF_RELEASE(gAuthURLParser);
@@ -102,32 +104,41 @@ net_GetStdURLParser()
 }
 
 //---------------------------------------------------------------------------
 // GetFileFromURLSpec implementations
 //---------------------------------------------------------------------------
 nsresult
 net_GetURLSpecFromDir(nsIFile *aFile, nsACString &result)
 {
+#if defined(MOZILLA_XPCOMRT_API)
+    NS_WARNING("net_GetURLSpecFromDir not implemented");
+    return NS_ERROR_NOT_IMPLEMENTED;
+#else
     nsAutoCString escPath;
     nsresult rv = net_GetURLSpecFromActualFile(aFile, escPath);
     if (NS_FAILED(rv))
         return rv;
 
     if (escPath.Last() != '/') {
         escPath += '/';
     }
     
     result = escPath;
     return NS_OK;
+#endif // defined(MOZILLA_XPCOMRT_API)
 }
 
 nsresult
 net_GetURLSpecFromFile(nsIFile *aFile, nsACString &result)
 {
+#if defined(MOZILLA_XPCOMRT_API)
+    NS_WARNING("net_GetURLSpecFromFile not implemented");
+    return NS_ERROR_NOT_IMPLEMENTED;
+#else
     nsAutoCString escPath;
     nsresult rv = net_GetURLSpecFromActualFile(aFile, escPath);
     if (NS_FAILED(rv))
         return rv;
 
     // if this file references a directory, then we need to ensure that the
     // URL ends with a slash.  this is important since it affects the rules
     // for relative URL resolution when this URL is used as a base URL.
@@ -137,16 +148,17 @@ net_GetURLSpecFromFile(nsIFile *aFile, n
         bool dir;
         rv = aFile->IsDirectory(&dir);
         if (NS_SUCCEEDED(rv) && dir)
             escPath += '/';
     }
     
     result = escPath;
     return NS_OK;
+#endif // defined(MOZILLA_XPCOMRT_API)
 }
 
 //----------------------------------------------------------------------------
 // file:// URL parsing
 //----------------------------------------------------------------------------
 
 nsresult
 net_ParseFileURL(const nsACString &inURL,
--- a/netwerk/dns/nsDNSService2.cpp
+++ b/netwerk/dns/nsDNSService2.cpp
@@ -31,17 +31,19 @@
 #include "nsNetAddr.h"
 #include "nsProxyRelease.h"
 #include "nsIObserverService.h"
 #include "nsINetworkLinkService.h"
 
 #include "mozilla/Attributes.h"
 #include "mozilla/VisualEventTracer.h"
 #include "mozilla/net/NeckoCommon.h"
+#if !defined(MOZILLA_XPCOMRT_API)
 #include "mozilla/net/ChildDNSService.h"
+#endif // !defined(MOZILLA_XPCOMRT_API)
 #include "mozilla/net/DNSListenerProxy.h"
 #include "mozilla/Services.h"
 
 using namespace mozilla;
 using namespace mozilla::net;
 
 static const char kPrefDnsCacheEntries[]     = "network.dnsCacheEntries";
 static const char kPrefDnsCacheExpiration[]  = "network.dnsCacheExpiration";
@@ -497,19 +499,21 @@ NS_IMPL_ISUPPORTS(nsDNSService, nsIDNSSe
  * nsDNSService impl:
  * singleton instance ctor/dtor methods
  ******************************************************************************/
 static nsDNSService *gDNSService;
 
 nsIDNSService*
 nsDNSService::GetXPCOMSingleton()
 {
+#if !defined(MOZILLA_XPCOMRT_API)
     if (IsNeckoChild()) {
         return ChildDNSService::GetSingleton();
     }
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
     return GetSingleton();
 }
 
 nsDNSService*
 nsDNSService::GetSingleton()
 {
     NS_ASSERTION(!IsNeckoChild(), "not a parent process");
@@ -635,25 +639,29 @@ nsDNSService::Init()
         }
         mNotifyResolution = notifyResolution;
         if (mNotifyResolution) {
             mObserverService =
               new nsMainThreadPtrHolder<nsIObserverService>(obs);
         }
     }
 
+#if !defined(MOZILLA_XPCOMRT_API)
     RegisterWeakMemoryReporter(this);
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
     return rv;
 }
 
 NS_IMETHODIMP
 nsDNSService::Shutdown()
 {
+#if !defined(MOZILLA_XPCOMRT_API)
     UnregisterWeakMemoryReporter(this);
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
     nsRefPtr<nsHostResolver> res;
     {
         MutexAutoLock lock(mLock);
         res = mResolver;
         mResolver = nullptr;
     }
     if (res)
--- a/netwerk/moz.build
+++ b/netwerk/moz.build
@@ -11,16 +11,17 @@ DIRS += [
     'socket',
     'mime',
     'streamconv',
     'cache',
     'cache2',
     'protocol',
     'system',
     'ipc',
+    'standalone',
 ]
 
 if CONFIG['MOZ_SRTP']:
     DIRS += ['srtp/src']
 
 if CONFIG['MOZ_SCTP']:
     DIRS += ['sctp/src', 'sctp/datachannel']
 
new file mode 100644
--- /dev/null
+++ b/netwerk/standalone/moz.build
@@ -0,0 +1,53 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+if CONFIG['OS_TARGET'] != 'WINNT' and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
+    Library('necko_standalone')
+
+src_list = [
+    'nsNetModuleStandalone.cpp',
+]
+
+netwerk_base_src = [
+    'nsDNSPrefetch.cpp',
+    'nsNetAddr.cpp',
+    'nsSocketTransportService2.cpp',
+    'nsURLHelper.cpp',
+]
+src_list += [
+    '%s/netwerk/base/%s' % (TOPSRCDIR, s) for s in netwerk_base_src
+]
+
+netwerk_dns_src = [
+    'nsHostResolver.cpp',
+    'DNS.cpp',
+    'DNSListenerProxy.cpp',
+    'GetAddrInfo.cpp',
+    'nameprep.c',
+    'nsDNSService2.cpp',
+    'nsIDNService.cpp',
+    'punycode.c',
+    'race.c',
+]
+src_list += [
+    '%s/netwerk/dns/%s' % (TOPSRCDIR, s) for s in netwerk_dns_src
+]
+
+SOURCES += sorted(src_list)
+
+FAIL_ON_WARNINGS = True
+
+LOCAL_INCLUDES = [
+    '../base',
+    '../build',
+    '../dns',
+]
+
+DEFINES['MOZILLA_INTERNAL_API'] = True
+DEFINES['MOZILLA_XPCOMRT_API'] = True
+DEFINES['MOZILLA_EXTERNAL_LINKAGE'] = True
+
+include('/ipc/chromium/chromium-config.mozbuild')
new file mode 100644
--- /dev/null
+++ b/netwerk/standalone/nsNetModuleStandalone.cpp
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 ts=8 et tw=80 : */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "necko-config.h"
+
+#include "mozilla/ModuleUtils.h"
+#include "mozilla/DebugOnly.h"
+#include "nsCOMPtr.h"
+#include "nsICategoryManager.h"
+#include "nsIClassInfoImpl.h"
+#include "nsIComponentManager.h"
+#include "nsIServiceManager.h"
+#include "nsNetCID.h"
+#include "nsPIDNSService.h"
+#include "nsPISocketTransportService.h"
+#include "nscore.h"
+
+extern const mozilla::Module kNeckoStandaloneModule;
+
+namespace mozilla {
+
+nsresult
+InitNetModuleStandalone()
+{
+  nsresult rv;
+
+  nsCOMPtr<nsPIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv);
+  if (NS_SUCCEEDED(rv)) {
+    mozilla::DebugOnly<nsresult> rv = dns->Init();
+    NS_ASSERTION(NS_SUCCEEDED(rv), "DNS service init failed");
+  } else {
+    NS_WARNING("failed to get dns service");
+  }
+
+  nsCOMPtr<nsPISocketTransportService> sts = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
+  if (NS_SUCCEEDED(rv)) {
+    mozilla::DebugOnly<nsresult> rv = sts->Init();
+    NS_ASSERTION(NS_SUCCEEDED(rv), "Socket transport service init failed");
+  } else {
+    NS_WARNING("failed to get socket transport service");
+  }
+
+  return NS_OK;
+}
+
+nsresult
+ShutdownNetModuleStandalone()
+{
+  nsresult rv;
+
+  nsCOMPtr<nsPIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv);
+  if (NS_SUCCEEDED(rv)) {
+    mozilla::DebugOnly<nsresult> rv = dns->Shutdown();
+    NS_ASSERTION(NS_SUCCEEDED(rv), "DNS service shutdown failed");
+  } else {
+    NS_WARNING("failed to get dns service");
+  }
+
+  nsCOMPtr<nsPISocketTransportService> sts = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
+  if (NS_SUCCEEDED(rv)) {
+    mozilla::DebugOnly<nsresult> rv = sts->Shutdown();
+    NS_ASSERTION(NS_SUCCEEDED(rv), "Socket transport service shutdown failed");
+  } else {
+    NS_WARNING("failed to get socket transport service");
+  }
+
+  return NS_OK;
+}
+
+} // namespace mozilla
+
+#include "nsDNSService2.h"
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIDNSService,
+  nsDNSService::GetXPCOMSingleton)
+
+#include "nsSocketTransportService2.h"
+#undef LOG
+#undef LOG_ENABLED
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSocketTransportService, Init)
+
+// Net module startup hook
+static nsresult nsNetStartup()
+{
+    return NS_OK;
+}
+
+// Net module shutdown hook
+static void nsNetShutdown()
+{
+}
+
+NS_DEFINE_NAMED_CID(NS_SOCKETTRANSPORTSERVICE_CID);
+NS_DEFINE_NAMED_CID(NS_DNSSERVICE_CID);
+
+static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
+    { &kNS_SOCKETTRANSPORTSERVICE_CID, false, nullptr, nsSocketTransportServiceConstructor },
+    { &kNS_DNSSERVICE_CID, false, nullptr, nsIDNSServiceConstructor },
+    { nullptr }
+};
+
+static const mozilla::Module::ContractIDEntry kNeckoContracts[] = {
+    { NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &kNS_SOCKETTRANSPORTSERVICE_CID },
+    { NS_DNSSERVICE_CONTRACTID, &kNS_DNSSERVICE_CID },
+    { nullptr }
+};
+
+const mozilla::Module kNeckoStandaloneModule = {
+    mozilla::Module::kVersion,
+    kNeckoCIDs,
+    kNeckoContracts,
+    nullptr,
+    nullptr,
+    nsNetStartup,
+    nsNetShutdown
+};
new file mode 100644
--- /dev/null
+++ b/netwerk/standalone/nsNetModuleStandalone.h
@@ -0,0 +1,13 @@
+#ifndef ns_net_module_standalone_h_
+#define ns_net_module_standalone_h_
+
+#include <nsError.h>
+
+namespace mozilla {
+
+nsresult InitNetModuleStandalone();
+nsresult ShutdownNetModuleStandalone();
+
+}
+
+#endif //  ns_net_module_standalone_h_
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -391,16 +391,17 @@ nsComponentManagerImpl::Init()
     return rv;
   }
 
   nsCategoryManager::GetSingleton()->SuppressNotifications(true);
 #endif
 
 #if defined(MOZILLA_XPCOMRT_API)
   RegisterModule(&kXPCOMRTModule, nullptr);
+  RegisterModule(&kNeckoStandaloneModule, nullptr);
 #else
   RegisterModule(&kXPCOMModule, nullptr);
 #endif // defined(MOZILLA_XPCOMRT_API)
 
   for (uint32_t i = 0; i < sStaticModules->Length(); ++i) {
     RegisterModule((*sStaticModules)[i], nullptr);
   }
 
--- a/xpcom/components/nsComponentManager.h
+++ b/xpcom/components/nsComponentManager.h
@@ -64,16 +64,17 @@ extern const char staticComponentType[];
 
 #ifdef DEBUG
 #define XPCOM_CHECK_PENDING_CIDS
 #endif
 ////////////////////////////////////////////////////////////////////////////////
 
 #if defined(MOZILLA_XPCOMRT_API)
 extern const mozilla::Module kXPCOMRTModule;
+extern const mozilla::Module kNeckoStandaloneModule;
 #else
 extern const mozilla::Module kXPCOMModule;
 #endif
 
 /**
  * This is a wrapper around mozilla::Mutex which provides runtime
  * checking for a deadlock where the same thread tries to lock a mutex while
  * it is already locked. This checking is present in both debug and release
--- a/xpcom/libxpcomrt/XPCOMRTInit.cpp
+++ b/xpcom/libxpcomrt/XPCOMRTInit.cpp
@@ -8,16 +8,18 @@
 #include "mozilla/ModuleUtils.h"
 #include "mozilla/NullPtr.h"
 #include "mozilla/TimeStamp.h"
 #include "nsCategoryManager.h"
 #include "nsComponentManager.h"
 #include "nsDebugImpl.h"
 #include "nsIErrorService.h"
 #include "nsMemoryImpl.h"
+#include "nsNetCID.h"
+#include "nsNetModuleStandalone.h"
 #include "nsObserverService.h"
 #include "nsThreadManager.h"
 #include "nsThreadPool.h"
 #include "nsUUIDGenerator.h"
 #include "nsXPCOMCIDInternal.h"
 #include "nsXPCOMPrivate.h"
 #include "TimerThread.h"
 #include "XPCOMRTInit.h"
@@ -93,16 +95,18 @@ NS_InitXPCOMRT()
   NS_ADDREF(nsComponentManagerImpl::gComponentManager);
 
   rv = nsComponentManagerImpl::gComponentManager->Init();
   if (NS_FAILED(rv)) {
     NS_RELEASE(nsComponentManagerImpl::gComponentManager);
     return rv;
   }
 
+  mozilla::InitNetModuleStandalone();
+
   return NS_OK;
 }
 
 nsresult
 NS_ShutdownXPCOMRT()
 {
   nsresult rv = NS_OK;
 
@@ -147,16 +151,21 @@ NS_ShutdownXPCOMRT()
     NS_ProcessPendingEvents(thread);
 
     // Shutdown the timer thread and all timers that might still be alive before
     // shutting down the component manager
     nsTimerImpl::Shutdown();
 
     NS_ProcessPendingEvents(thread);
 
+    // Net module needs to be shutdown before the thread manager or else
+    // the thread manager will hang waiting for the socket transport
+    // service to shutdown.
+    mozilla::ShutdownNetModuleStandalone();
+
     // Shutdown all remaining threads.  This method does not return until
     // all threads created using the thread manager (with the exception of
     // the main thread) have exited.
     nsThreadManager::get()->Shutdown();
 
     NS_ProcessPendingEvents(thread);
   }
 
--- a/xpcom/libxpcomrt/moz.build
+++ b/xpcom/libxpcomrt/moz.build
@@ -136,16 +136,17 @@ if CONFIG['INTEL_ARCHITECTURE']:
 GENERATED_INCLUDES += ['..']
 LOCAL_INCLUDES = [
     '../base',
     '../build',
     '../components',
     '../ds',
     '../glue',
     '../threads',
+    '/netwerk/standalone/',
     '/xpcom/reflect/xptinfo/',
 ]
 
 DEFINES['MOZILLA_INTERNAL_API'] = True
 DEFINES['MOZILLA_XPCOMRT_API'] = True
 DEFINES['MOZILLA_EXTERNAL_LINKAGE'] = True
 
 include('/ipc/chromium/chromium-config.mozbuild')