Bug 1430857: Part 1 - Refactor DllServices to make it possible to obtain them from anywhere in Gecko; r?jimm draft
authorAaron Klotz <aklotz@mozilla.com>
Tue, 30 Jan 2018 14:23:10 -0700
changeset 752405 0fff8432689dced988ad4a6572ca60230f74ca85
parent 751787 0790ec12200d5f663dd000a6ef3c72c795ca4ead
child 752406 8469b9ba50cfc80ab46456f3a397803a5fda4754
push id98254
push useraklotz@mozilla.com
push dateThu, 08 Feb 2018 04:45:45 +0000
reviewersjimm
bugs1430857
milestone60.0a1
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,26 @@ if CONFIG['MOZ_WIDGET_TOOLKIT']:
         SOURCES += [
             'WindowsDllBlocklist.cpp',
         ]
 
         DisableStlWrapping()
         OS_LIBS += [
             'version',
         ]
+        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;