Bug 1430857: Part 1 - Refactor DllServices to make it possible to obtain them from anywhere in Gecko; r=jimm
☠☠ backed out by 7a990bbf6046 ☠ ☠
authorAaron Klotz <aklotz@mozilla.com>
Tue, 30 Jan 2018 14:23:10 -0700
changeset 402623 6b88557d1e500c8d21fa57e6f48642a5d72a3c09
parent 402577 87b9333134d1ed8833dda6514d729de3930dc54b
child 402624 b12ea04f9c5ae5626fda1968e5c1cbc98bdebcb6
push id33394
push userrgurzau@mozilla.com
push dateWed, 07 Feb 2018 00:14:43 +0000
treeherdermozilla-central@f033d62a90ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs1430857
milestone60.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 1430857: Part 1 - Refactor DllServices to make it possible to obtain them from anywhere in Gecko; r=jimm MozReview-Commit-ID: GfWata0eCc5
mozglue/build/WindowsDllBlocklist.cpp
mozglue/build/WindowsDllBlocklist.h
mozglue/build/WindowsDllServices.h
mozglue/build/moz.build
toolkit/xre/WinDllServices.cpp
toolkit/xre/WinDllServices.h
toolkit/xre/moz.build
toolkit/xre/nsAppRunner.cpp
--- a/mozglue/build/WindowsDllBlocklist.cpp
+++ b/mozglue/build/WindowsDllBlocklist.cpp
@@ -19,26 +19,25 @@
 #include <io.h>
 
 #pragma warning( push )
 #pragma warning( disable : 4275 4530 ) // See msvc-stl-wrapper.template.h
 #include <map>
 #pragma warning( pop )
 
 #include "nsAutoPtr.h"
-
 #include "nsWindowsDllInterceptor.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/StackWalk_windows.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/WindowsVersion.h"
 #include "nsWindowsHelpers.h"
 #include "WindowsDllBlocklist.h"
 #include "mozilla/AutoProfilerLabel.h"
-#include "mozilla/WindowsDllServices.h"
+#include "mozilla/glue/WindowsDllServices.h"
 
 using namespace mozilla;
 
 #define ALL_VERSIONS   ((unsigned long long)-1LL)
 
 // DLLs sometimes ship without a version number, particularly early
 // releases. Blocking "version <= 0" has the effect of blocking unversioned
 // DLLs (since the call to get version info fails), but not blocking
@@ -933,17 +932,17 @@ DllBlocklist_CheckStatus()
 }
 
 // ============================================================================
 // This section is for DLL Services
 // ============================================================================
 
 
 static SRWLOCK gDllServicesLock = SRWLOCK_INIT;
-static mozilla::detail::DllServicesBase* gDllServices;
+static mozilla::glue::detail::DllServicesBase* gDllServices;
 
 class MOZ_RAII AutoSharedLock final
 {
 public:
   explicit AutoSharedLock(SRWLOCK& aLock)
     : mLock(aLock)
   {
     ::AcquireSRWLockShared(&aLock);
@@ -1043,17 +1042,17 @@ DllLoadNotification(ULONG aReason, PCLDR
     return;
   }
 
   PCUNICODE_STRING fullDllName = aNotificationData->Loaded.FullDllName;
   gDllServices->DispatchDllLoadNotification(fullDllName);
 }
 
 MFBT_API void
-DllBlocklist_SetDllServices(mozilla::detail::DllServicesBase* aSvc)
+DllBlocklist_SetDllServices(mozilla::glue::detail::DllServicesBase* aSvc)
 {
   AutoExclusiveLock lock(gDllServicesLock);
 
   if (aSvc && !gNotificationCookie) {
     auto pLdrRegisterDllNotification =
       reinterpret_cast<decltype(&::LdrRegisterDllNotification)>(
         ::GetProcAddress(::GetModuleHandleW(L"ntdll.dll"),
                          "LdrRegisterDllNotification"));
--- a/mozglue/build/WindowsDllBlocklist.h
+++ b/mozglue/build/WindowsDllBlocklist.h
@@ -21,17 +21,19 @@ enum DllBlocklistInitFlags
 };
 
 MFBT_API void DllBlocklist_Initialize(uint32_t aInitFlags = eDllBlocklistInitFlagDefault);
 MFBT_API void DllBlocklist_WriteNotes(HANDLE file);
 MFBT_API bool DllBlocklist_CheckStatus();
 
 // Forward declaration
 namespace mozilla {
+namespace glue {
 namespace detail {
 class DllServicesBase;
 } // namespace detail
+} // namespace glue
 } // namespace mozilla
 
-MFBT_API void DllBlocklist_SetDllServices(mozilla::detail::DllServicesBase* aSvc);
+MFBT_API void DllBlocklist_SetDllServices(mozilla::glue::detail::DllServicesBase* aSvc);
 
 #endif // defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
 #endif // mozilla_windowsdllblocklist_h
--- a/mozglue/build/WindowsDllServices.h
+++ b/mozglue/build/WindowsDllServices.h
@@ -1,32 +1,33 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 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/. */
 
-#ifndef mozilla_WindowsDllServices_h
-#define mozilla_WindowsDllServices_h
+#ifndef mozilla_glue_WindowsDllServices_h
+#define mozilla_glue_WindowsDllServices_h
 
 #include "mozilla/WindowsDllBlocklist.h"
 
 #if defined(MOZILLA_INTERNAL_API)
 
 #include "mozilla/SystemGroup.h"
 #include "nsISupportsImpl.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 
 #endif // defined(MOZILLA_INTERNAL_API)
 
 // For PCUNICODE_STRING
 #include <winternl.h>
 
 namespace mozilla {
+namespace glue {
 namespace detail {
 
 class DllServicesBase
 {
 public:
   /**
    * WARNING: This method is called from within an unsafe context that holds
    *          multiple locks inside the Windows loader. The only thing that
@@ -81,11 +82,12 @@ protected:
   DllServices() = default;
   ~DllServices() = default;
 
   virtual void NotifyDllLoad(const bool aIsMainThread, const nsString& aDllName) = 0;
 };
 
 #endif // defined(MOZILLA_INTERNAL_API)
 
+} // namespace glue
 } // namespace mozilla
 
-#endif // mozilla_WindowsDllServices_h
+#endif // mozilla_glue_WindowsDllServices_h
--- a/mozglue/build/moz.build
+++ b/mozglue/build/moz.build
@@ -58,24 +58,28 @@ if CONFIG['MOZ_WIDGET_TOOLKIT']:
         SOURCES += [
             'WindowsDllBlocklist.cpp',
         ]
 
         DisableStlWrapping()
         OS_LIBS += [
             'version',
         ]
+        EXPORTS.mozilla += [
+            'WindowsDllBlocklist.h',
+        ]
+        EXPORTS.mozilla.glue += [
+            'WindowsDllServices.h',
+        ]
 
     EXPORTS.mozilla += [
         'arm.h',
         'mips.h',
         'SSE.h',
         'WindowsCFGStatus.h',
-        'WindowsDllBlocklist.h',
-        'WindowsDllServices.h',
     ]
 
     if CONFIG['CPU_ARCH'].startswith('x86'):
         SOURCES += [
             'SSE.cpp',
         ]
 
     if CONFIG['CPU_ARCH'] == 'arm':
new file mode 100644
--- /dev/null
+++ b/toolkit/xre/WinDllServices.cpp
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 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 https://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/WinDllServices.h"
+
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/Services.h"
+#include "nsIObserverService.h"
+#include "nsString.h"
+
+namespace mozilla {
+
+const char* DllServices::kTopicDllLoadedMainThread = "dll-loaded-main-thread";
+const char* DllServices::kTopicDllLoadedNonMainThread = "dll-loaded-non-main-thread";
+
+static StaticRefPtr<DllServices> sInstance;
+
+DllServices*
+DllServices::Get()
+{
+  if (sInstance) {
+    return sInstance;
+  }
+
+  sInstance = new DllServices();
+  ClearOnShutdown(&sInstance);
+  return sInstance;
+}
+
+DllServices::DllServices()
+{
+  Enable();
+}
+
+void
+DllServices::NotifyDllLoad(const bool aIsMainThread, const nsString& aDllName)
+{
+  const char* topic;
+
+  if (aIsMainThread) {
+    topic = kTopicDllLoadedMainThread;
+  } else {
+    topic = kTopicDllLoadedNonMainThread;
+  }
+
+  nsCOMPtr<nsIObserverService> obsServ(mozilla::services::GetObserverService());
+  obsServ->NotifyObservers(nullptr, topic, aDllName.get());
+}
+
+} // namespace mozilla
+
new file mode 100644
--- /dev/null
+++ b/toolkit/xre/WinDllServices.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 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 https://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_WinDllServices_h
+#define mozilla_WinDllServices_h
+
+#include "mozilla/glue/WindowsDllServices.h"
+
+namespace mozilla {
+
+class DllServices : public mozilla::glue::DllServices
+{
+public:
+  static DllServices* Get();
+
+  static const char* kTopicDllLoadedMainThread;
+  static const char* kTopicDllLoadedNonMainThread;
+
+private:
+  DllServices();
+  ~DllServices() = default;
+
+  void NotifyDllLoad(const bool aIsMainThread, const nsString& aDllName) override;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_WinDllServices_h
--- a/toolkit/xre/moz.build
+++ b/toolkit/xre/moz.build
@@ -31,21 +31,25 @@ EXPORTS += [
 ]
 
 EXPORTS.mozilla += ['AutoSQLiteLifetime.h', 'Bootstrap.h']
 
 if CONFIG['MOZ_INSTRUMENT_EVENT_LOOP']:
     EXPORTS += ['EventTracer.h']
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
+    EXPORTS.mozilla += [
+        'WinDllServices.h',
+    ]
     SOURCES += [
         '../../other-licenses/nsis/Contrib/CityHash/cityhash/city.cpp',
     ]
     UNIFIED_SOURCES += [
         'nsNativeAppSupportWin.cpp',
+        'WinDllServices.cpp',
     ]
     DEFINES['PROXY_PRINTING'] = 1
     LOCAL_INCLUDES += [
         '../../other-licenses/nsis/Contrib/CityHash/cityhash',
         '../components/printingui',
     ]
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     UNIFIED_SOURCES += [
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -155,17 +155,17 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <pwd.h>
 #endif
 
 #ifdef XP_WIN
 #include <process.h>
 #include <shlobj.h>
-#include "mozilla/WindowsDllServices.h"
+#include "mozilla/WinDllServices.h"
 #include "nsThreadUtils.h"
 #include <comdef.h>
 #include <wbemidl.h>
 #include "WinUtils.h"
 #endif
 
 #ifdef XP_MACOSX
 #include "nsILocalFileMac.h"
@@ -1660,50 +1660,16 @@ ScopedXPCOMStartup::CreateAppSupport(nsI
   if (!gNativeAppSupport)
     return NS_ERROR_NOT_INITIALIZED;
 
   return gNativeAppSupport->QueryInterface(aIID, aResult);
 }
 
 nsINativeAppSupport* ScopedXPCOMStartup::gNativeAppSupport;
 
-#if defined(XP_WIN)
-
-class DllNotifications : public mozilla::DllServices
-{
-public:
-  DllNotifications()
-  {
-    Enable();
-  }
-
-private:
-  ~DllNotifications() = default;
-
-  void NotifyDllLoad(const bool aIsMainThread, const nsString& aDllName) override;
-};
-
-void
-DllNotifications::NotifyDllLoad(const bool aIsMainThread,
-                                const nsString& aDllName)
-{
-  const char* topic;
-
-  if (aIsMainThread) {
-    topic = "dll-loaded-main-thread";
-  } else {
-    topic = "dll-loaded-non-main-thread";
-  }
-
-  nsCOMPtr<nsIObserverService> obsServ(mozilla::services::GetObserverService());
-  obsServ->NotifyObservers(nullptr, topic, aDllName.get());
-}
-
-#endif // defined(XP_WIN)
-
 static void DumpArbitraryHelp()
 {
   nsresult rv;
 
   ScopedLogging log;
 
   {
     ScopedXPCOMStartup xpcom;
@@ -4339,19 +4305,19 @@ void AddSandboxAnnotations()
  */
 nsresult
 XREMain::XRE_mainRun()
 {
   nsresult rv = NS_OK;
   NS_ASSERTION(mScopedXPCOM, "Scoped xpcom not initialized.");
 
 #if defined(XP_WIN)
-  RefPtr<DllNotifications> dllNotifications(new DllNotifications());
-  auto dllNotificationsDisable = MakeScopeExit([&dllNotifications]() {
-    dllNotifications->Disable();
+  RefPtr<mozilla::DllServices> dllServices(mozilla::DllServices::Get());
+  auto dllServicesDisable = MakeScopeExit([&dllServices]() {
+    dllServices->Disable();
   });
 #endif // defined(XP_WIN)
 
 #ifdef NS_FUNCTION_TIMER
   // initialize some common services, so we don't pay the cost for these at odd times later on;
   // SetWindowCreator -> ChromeRegistry -> IOService -> SocketTransportService -> (nspr wspm init), Prefs
   {
     nsCOMPtr<nsISupports> comp;