xpcom/build/nsXPComInit.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* vim:set ts=4 sw=4 sts=4 ci et: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "base/basictypes.h"
     9 #include "mozilla/Atomics.h"
    10 #include "mozilla/Poison.h"
    11 #include "mozilla/Preferences.h"
    12 #include "mozilla/XPCOM.h"
    13 #include "nsXULAppAPI.h"
    15 #include "nsXPCOMPrivate.h"
    16 #include "nsXPCOMCIDInternal.h"
    18 #include "mozilla/layers/ImageBridgeChild.h"
    19 #include "mozilla/layers/CompositorParent.h"
    21 #include "prlink.h"
    23 #include "nsCycleCollector.h"
    24 #include "nsObserverList.h"
    25 #include "nsObserverService.h"
    26 #include "nsProperties.h"
    27 #include "nsPersistentProperties.h"
    28 #include "nsScriptableInputStream.h"
    29 #include "nsBinaryStream.h"
    30 #include "nsStorageStream.h"
    31 #include "nsPipe.h"
    32 #include "nsScriptableBase64Encoder.h"
    34 #include "nsMemoryImpl.h"
    35 #include "nsDebugImpl.h"
    36 #include "nsTraceRefcnt.h"
    37 #include "nsErrorService.h"
    39 #include "nsSupportsArray.h"
    40 #include "nsArray.h"
    41 #include "nsINIParserImpl.h"
    42 #include "nsSupportsPrimitives.h"
    43 #include "nsConsoleService.h"
    45 #include "nsIJSRuntimeService.h"
    47 #include "nsComponentManager.h"
    48 #include "nsCategoryManagerUtils.h"
    49 #include "nsIServiceManager.h"
    51 #include "nsThreadManager.h"
    52 #include "nsThreadPool.h"
    54 #include "xptinfo.h"
    55 #include "nsIInterfaceInfoManager.h"
    56 #include "xptiprivate.h"
    57 #include "mozilla/XPTInterfaceInfoManager.h"
    59 #include "nsTimerImpl.h"
    60 #include "TimerThread.h"
    62 #include "nsThread.h"
    63 #include "nsProcess.h"
    64 #include "nsEnvironment.h"
    65 #include "nsVersionComparatorImpl.h"
    67 #include "nsIFile.h"
    68 #include "nsLocalFile.h"
    69 #if defined(XP_UNIX)
    70 #include "nsNativeCharsetUtils.h"
    71 #endif
    72 #include "nsDirectoryService.h"
    73 #include "nsDirectoryServiceDefs.h"
    74 #include "nsCategoryManager.h"
    75 #include "nsICategoryManager.h"
    76 #include "nsMultiplexInputStream.h"
    78 #include "nsStringStream.h"
    79 extern nsresult nsStringInputStreamConstructor(nsISupports *, REFNSIID, void **);
    81 #include "nsAtomService.h"
    82 #include "nsAtomTable.h"
    83 #include "nsISupportsImpl.h"
    85 #include "nsHashPropertyBag.h"
    87 #include "nsUnicharInputStream.h"
    88 #include "nsVariant.h"
    90 #include "nsUUIDGenerator.h"
    92 #include "nsIOUtil.h"
    94 #include "SpecialSystemDirectory.h"
    96 #if defined(XP_WIN)
    97 #include "nsWindowsRegKey.h"
    98 #endif
   100 #ifdef MOZ_WIDGET_COCOA
   101 #include "nsMacUtilsImpl.h"
   102 #endif
   104 #include "nsSystemInfo.h"
   105 #include "nsMemoryReporterManager.h"
   106 #include "nsMemoryInfoDumper.h"
   107 #include "nsSecurityConsoleMessage.h"
   108 #include "nsMessageLoop.h"
   110 #include "nsStatusReporterManager.h"
   112 #include <locale.h>
   113 #include "mozilla/Services.h"
   114 #include "mozilla/Omnijar.h"
   115 #include "mozilla/HangMonitor.h"
   116 #include "mozilla/Telemetry.h"
   117 #include "mozilla/BackgroundHangMonitor.h"
   119 #include "nsChromeRegistry.h"
   120 #include "nsChromeProtocolHandler.h"
   121 #include "mozilla/PoisonIOInterposer.h"
   122 #include "mozilla/LateWriteChecks.h"
   124 #include "mozilla/scache/StartupCache.h"
   126 #include "base/at_exit.h"
   127 #include "base/command_line.h"
   128 #include "base/message_loop.h"
   130 #include "mozilla/ipc/BrowserProcessSubThread.h"
   131 #include "mozilla/AvailableMemoryTracker.h"
   132 #include "mozilla/ClearOnShutdown.h"
   133 #include "mozilla/SystemMemoryReporter.h"
   135 #ifdef MOZ_VISUAL_EVENT_TRACER
   136 #include "mozilla/VisualEventTracer.h"
   137 #endif
   139 #include "ogg/ogg.h"
   140 #if defined(MOZ_VPX) && !defined(MOZ_VPX_NO_MEM_REPORTING)
   141 #include "vpx_mem/vpx_mem.h"
   142 #endif
   143 #ifdef MOZ_WEBM
   144 #include "nestegg/nestegg.h"
   145 #endif
   147 #include "GeckoProfiler.h"
   149 #include "jsapi.h"
   151 using namespace mozilla;
   152 using base::AtExitManager;
   153 using mozilla::ipc::BrowserProcessSubThread;
   154 #ifdef MOZ_VISUAL_EVENT_TRACER
   155 using mozilla::eventtracer::VisualEventTracer;
   156 #endif
   158 namespace {
   160 static AtExitManager* sExitManager;
   161 static MessageLoop* sMessageLoop;
   162 static bool sCommandLineWasInitialized;
   163 static BrowserProcessSubThread* sIOThread;
   164 static BackgroundHangMonitor* sMainHangMonitor;
   166 } /* anonymous namespace */
   168 // Registry Factory creation function defined in nsRegistry.cpp
   169 // We hook into this function locally to create and register the registry
   170 // Since noone outside xpcom needs to know about this and nsRegistry.cpp
   171 // does not have a local include file, we are putting this definition
   172 // here rather than in nsIRegistry.h
   173 extern nsresult NS_RegistryGetFactory(nsIFactory** aFactory);
   174 extern nsresult NS_CategoryManagerGetFactory( nsIFactory** );
   176 #ifdef XP_WIN
   177 extern nsresult CreateAnonTempFileRemover();
   178 #endif
   180 NS_GENERIC_FACTORY_CONSTRUCTOR(nsProcess)
   182 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsIDImpl)
   183 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsStringImpl)
   184 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsCStringImpl)
   185 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRBoolImpl)
   186 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint8Impl)
   187 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint16Impl)
   188 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint32Impl)
   189 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint64Impl)
   190 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRTimeImpl)
   191 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsCharImpl)
   192 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt16Impl)
   193 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt32Impl)
   194 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt64Impl)
   195 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsFloatImpl)
   196 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsDoubleImpl)
   197 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsVoidImpl)
   198 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsInterfacePointerImpl)
   200 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsConsoleService, Init)
   201 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAtomService)
   202 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimerImpl)
   203 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryOutputStream)
   204 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryInputStream)
   205 NS_GENERIC_FACTORY_CONSTRUCTOR(nsStorageStream)
   206 NS_GENERIC_FACTORY_CONSTRUCTOR(nsVersionComparatorImpl)
   207 NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptableBase64Encoder)
   208 #ifdef MOZ_VISUAL_EVENT_TRACER
   209 NS_GENERIC_FACTORY_CONSTRUCTOR(VisualEventTracer)
   210 #endif
   212 NS_GENERIC_FACTORY_CONSTRUCTOR(nsVariant)
   214 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHashPropertyBag)
   216 NS_GENERIC_AGGREGATED_CONSTRUCTOR(nsProperties)
   218 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUUIDGenerator, Init)
   220 #ifdef MOZ_WIDGET_COCOA
   221 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacUtilsImpl)
   222 #endif
   224 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemInfo, Init)
   226 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsMemoryReporterManager, Init)
   228 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMemoryInfoDumper)
   230 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsStatusReporterManager, Init)
   232 NS_GENERIC_FACTORY_CONSTRUCTOR(nsIOUtil)
   234 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSecurityConsoleMessage)
   236 static nsresult
   237 nsThreadManagerGetSingleton(nsISupports* outer,
   238                             const nsIID& aIID,
   239                             void* *aInstancePtr)
   240 {
   241     NS_ASSERTION(aInstancePtr, "null outptr");
   242     if (NS_WARN_IF(outer))
   243         return NS_ERROR_NO_AGGREGATION;
   245     return nsThreadManager::get()->QueryInterface(aIID, aInstancePtr);
   246 }
   248 NS_GENERIC_FACTORY_CONSTRUCTOR(nsThreadPool)
   250 static nsresult
   251 nsXPTIInterfaceInfoManagerGetSingleton(nsISupports* outer,
   252                                        const nsIID& aIID,
   253                                        void* *aInstancePtr)
   254 {
   255     NS_ASSERTION(aInstancePtr, "null outptr");
   256     if (NS_WARN_IF(outer))
   257         return NS_ERROR_NO_AGGREGATION;
   259     nsCOMPtr<nsIInterfaceInfoManager> iim
   260         (XPTInterfaceInfoManager::GetSingleton());
   261     if (!iim)
   262         return NS_ERROR_FAILURE;
   264     return iim->QueryInterface(aIID, aInstancePtr);
   265 }
   267 nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = nullptr;
   268 bool gXPCOMShuttingDown = false;
   269 bool gXPCOMThreadsShutDown = false;
   271 static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
   272 static NS_DEFINE_CID(kINIParserFactoryCID, NS_INIPARSERFACTORY_CID);
   273 static NS_DEFINE_CID(kSimpleUnicharStreamFactoryCID, NS_SIMPLE_UNICHAR_STREAM_FACTORY_CID);
   275 NS_DEFINE_NAMED_CID(NS_CHROMEREGISTRY_CID);
   276 NS_DEFINE_NAMED_CID(NS_CHROMEPROTOCOLHANDLER_CID);
   278 NS_DEFINE_NAMED_CID(NS_SECURITY_CONSOLE_MESSAGE_CID);
   280 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsChromeRegistry,
   281                                          nsChromeRegistry::GetSingleton)
   282 NS_GENERIC_FACTORY_CONSTRUCTOR(nsChromeProtocolHandler)
   284 #define NS_PERSISTENTPROPERTIES_CID NS_IPERSISTENTPROPERTIES_CID /* sigh */
   286 static already_AddRefed<nsIFactory>
   287 CreateINIParserFactory(const mozilla::Module& module,
   288                        const mozilla::Module::CIDEntry& entry)
   289 {
   290     nsCOMPtr<nsIFactory> f = new nsINIParserFactory();
   291     return f.forget();
   292 }
   294 static already_AddRefed<nsIFactory>
   295 CreateUnicharStreamFactory(const mozilla::Module& module,
   296                            const mozilla::Module::CIDEntry& entry)
   297 {
   298     return already_AddRefed<nsIFactory>(
   299             nsSimpleUnicharStreamFactory::GetInstance());
   300 }
   302 #define COMPONENT(NAME, Ctor) static NS_DEFINE_CID(kNS_##NAME##_CID, NS_##NAME##_CID);
   303 #include "XPCOMModule.inc"
   304 #undef COMPONENT
   306 #define COMPONENT(NAME, Ctor) { &kNS_##NAME##_CID, false, nullptr, Ctor },
   307 const mozilla::Module::CIDEntry kXPCOMCIDEntries[] = {
   308     { &kComponentManagerCID, true, nullptr, nsComponentManagerImpl::Create },
   309     { &kINIParserFactoryCID, false, CreateINIParserFactory },
   310     { &kSimpleUnicharStreamFactoryCID, false, CreateUnicharStreamFactory },
   311 #include "XPCOMModule.inc"
   312     { &kNS_CHROMEREGISTRY_CID, false, nullptr, nsChromeRegistryConstructor },
   313     { &kNS_CHROMEPROTOCOLHANDLER_CID, false, nullptr, nsChromeProtocolHandlerConstructor },
   314     { &kNS_SECURITY_CONSOLE_MESSAGE_CID, false, nullptr, nsSecurityConsoleMessageConstructor },
   315     { nullptr }
   316 };
   317 #undef COMPONENT
   319 #define COMPONENT(NAME, Ctor) { NS_##NAME##_CONTRACTID, &kNS_##NAME##_CID },
   320 const mozilla::Module::ContractIDEntry kXPCOMContracts[] = {
   321 #include "XPCOMModule.inc"
   322     { NS_CHROMEREGISTRY_CONTRACTID, &kNS_CHROMEREGISTRY_CID },
   323     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "chrome", &kNS_CHROMEPROTOCOLHANDLER_CID },
   324     { NS_INIPARSERFACTORY_CONTRACTID, &kINIParserFactoryCID },
   325     { NS_SECURITY_CONSOLE_MESSAGE_CONTRACTID, &kNS_SECURITY_CONSOLE_MESSAGE_CID },
   326     { nullptr }
   327 };
   328 #undef COMPONENT
   330 const mozilla::Module kXPCOMModule = { mozilla::Module::kVersion, kXPCOMCIDEntries, kXPCOMContracts };
   332 // gDebug will be freed during shutdown.
   333 static nsIDebug* gDebug = nullptr;
   335 EXPORT_XPCOM_API(nsresult)
   336 NS_GetDebug(nsIDebug** result)
   337 {
   338     return nsDebugImpl::Create(nullptr,
   339                                NS_GET_IID(nsIDebug),
   340                                (void**) result);
   341 }
   343 EXPORT_XPCOM_API(nsresult)
   344 NS_InitXPCOM(nsIServiceManager* *result,
   345                              nsIFile* binDirectory)
   346 {
   347     return NS_InitXPCOM2(result, binDirectory, nullptr);
   348 }
   350 class ICUReporter MOZ_FINAL : public nsIMemoryReporter,
   351                               public CountingAllocatorBase<ICUReporter>
   352 {
   353 public:
   354     NS_DECL_ISUPPORTS
   356     static void* Alloc(const void*, size_t size)
   357     {
   358         return CountingMalloc(size);
   359     }
   361     static void* Realloc(const void*, void* p, size_t size)
   362     {
   363         return CountingRealloc(p, size);
   364     }
   366     static void Free(const void*, void* p)
   367     {
   368         return CountingFree(p);
   369     }
   371 private:
   372     NS_IMETHODIMP
   373     CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData)
   374     {
   375         return MOZ_COLLECT_REPORT(
   376             "explicit/icu", KIND_HEAP, UNITS_BYTES, MemoryAllocated(),
   377             "Memory used by ICU, a Unicode and globalization support library.");
   378     }
   379 };
   381 NS_IMPL_ISUPPORTS(ICUReporter, nsIMemoryReporter)
   383 /* static */ template<> Atomic<size_t> CountingAllocatorBase<ICUReporter>::sAmount(0);
   385 class OggReporter MOZ_FINAL : public nsIMemoryReporter,
   386                               public CountingAllocatorBase<OggReporter>
   387 {
   388 public:
   389     NS_DECL_ISUPPORTS
   391 private:
   392     NS_IMETHODIMP
   393     CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData)
   394     {
   395         return MOZ_COLLECT_REPORT(
   396             "explicit/media/libogg", KIND_HEAP, UNITS_BYTES, MemoryAllocated(),
   397             "Memory allocated through libogg for Ogg, Theora, and related media files.");
   398     }
   399 };
   401 NS_IMPL_ISUPPORTS(OggReporter, nsIMemoryReporter)
   403 /* static */ template<> Atomic<size_t> CountingAllocatorBase<OggReporter>::sAmount(0);
   405 #ifdef MOZ_VPX
   406 class VPXReporter MOZ_FINAL : public nsIMemoryReporter,
   407                               public CountingAllocatorBase<VPXReporter>
   408 {
   409 public:
   410     NS_DECL_ISUPPORTS
   412 private:
   413     NS_IMETHODIMP
   414     CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData)
   415     {
   416         return MOZ_COLLECT_REPORT(
   417             "explicit/media/libvpx", KIND_HEAP, UNITS_BYTES, MemoryAllocated(),
   418             "Memory allocated through libvpx for WebM media files.");
   419     }
   420 };
   422 NS_IMPL_ISUPPORTS(VPXReporter, nsIMemoryReporter)
   424 /* static */ template<> Atomic<size_t> CountingAllocatorBase<VPXReporter>::sAmount(0);
   425 #endif /* MOZ_VPX */
   427 #ifdef MOZ_WEBM
   428 class NesteggReporter MOZ_FINAL : public nsIMemoryReporter
   429                                 , public CountingAllocatorBase<NesteggReporter>
   430 {
   431 public:
   432     NS_DECL_ISUPPORTS
   434 private:
   435     NS_IMETHODIMP
   436     CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData)
   437     {
   438         return MOZ_COLLECT_REPORT(
   439             "explicit/media/libnestegg", KIND_HEAP, UNITS_BYTES, MemoryAllocated(),
   440             "Memory allocated through libnestegg for WebM media files.");
   441     }
   442 };
   444 NS_IMPL_ISUPPORTS(NesteggReporter, nsIMemoryReporter)
   446 /* static */ template<> Atomic<size_t> CountingAllocatorBase<NesteggReporter>::sAmount(0);
   447 #endif /* MOZ_WEBM */
   449 // Anonymous namespace for customizing the default locale that JavaScript
   450 // uses, according to the value of the "javascript.default_locale" pref.
   451 // The current default locale can be detected in JavaScript by calling
   452 // `Intl.DateTimeFormat().resolvedOptions().locale`
   453 namespace {
   455 #define DEFAULT_LOCALE_PREF "javascript.default_locale"
   457 static char* sSystemLocale;
   458 static char* sJSLocale;
   460 // Returns a pointer to the current JS Runtime.
   461 static
   462 JSRuntime* GetRuntime() {
   463   nsresult rv;
   464   nsCOMPtr<nsIJSRuntimeService> rts = do_GetService("@mozilla.org/js/xpc/RuntimeService;1", &rv);
   465   if (NS_FAILED(rv)) return NULL;
   466   JSRuntime* rt;
   467   rts->GetRuntime(&rt);
   468   return rt;
   469 }
   471 // Takes the "javascript.default_locale" pref value and applies it. If the locale
   472 // is empty, we fall back to the default system and JS locales.
   473 static
   474 void DefaultLocaleChangedCallback(const char* /* pref */, void* /* closure */) {
   475   // Get a pointer to the default JS Runtime.
   476   JSRuntime* rt = GetRuntime();
   477   if (rt) {
   478     // Read the pref, which may contain a custom default locale to be used in JavaScript.
   479     nsAutoCString prefLocale;
   480     mozilla::Preferences::GetCString(DEFAULT_LOCALE_PREF, &prefLocale);
   481     // Set the application-wide C-locale. Needed for Date.toLocaleFormat().
   482     setlocale(LC_ALL, prefLocale.IsEmpty() ? sSystemLocale : prefLocale.get());
   483     // Now override the JavaScript Runtime Locale that is used by the Intl API
   484     // as well as Date.toLocaleString, Number.toLocaleString, and String.localeCompare.
   485     JS_SetDefaultLocale(rt, prefLocale.IsEmpty() ? sJSLocale : prefLocale.get());
   486   }
   487 }
   489 static
   490 void StartWatchingDefaultLocalePref() {
   491   // Get the default system locale. To be used if pref is not available.
   492   sSystemLocale = strdup(setlocale(LC_ALL,NULL));
   493   // Store the default JavaScript locale.
   494   JSRuntime* rt = GetRuntime();
   495   if (rt) {
   496     sJSLocale = strdup(JS_GetDefaultLocale(rt));
   497   }
   498   // Now keep the locale updated with the current pref value.
   499   mozilla::Preferences::RegisterCallbackAndCall(DefaultLocaleChangedCallback, DEFAULT_LOCALE_PREF);
   500 }
   502 static
   503 void StopWatchingDefaultLocalePref() {
   504   mozilla::Preferences::UnregisterCallback(DefaultLocaleChangedCallback, DEFAULT_LOCALE_PREF);
   505   if (sSystemLocale) free(sSystemLocale);
   506   if (sJSLocale) JS_free(nullptr, sJSLocale);
   507 }
   509 } // anonymous namespace for locale pref
   511 EXPORT_XPCOM_API(nsresult)
   512 NS_InitXPCOM2(nsIServiceManager* *result,
   513               nsIFile* binDirectory,
   514               nsIDirectoryServiceProvider* appFileLocationProvider)
   515 {
   516     mozPoisonValueInit();
   518     char aLocal;
   519     profiler_init(&aLocal);
   520     nsresult rv = NS_OK;
   522      // We are not shutting down
   523     gXPCOMShuttingDown = false;
   525     // Initialize the available memory tracker before other threads have had a
   526     // chance to start up, because the initialization is not thread-safe.
   527     mozilla::AvailableMemoryTracker::Init();
   529 #ifdef XP_UNIX
   530     // Discover the current value of the umask, and save it where
   531     // nsSystemInfo::Init can retrieve it when necessary.  There is no way
   532     // to read the umask without changing it, and the setting is process-
   533     // global, so this must be done while we are still single-threaded; the
   534     // nsSystemInfo object is typically created much later, when some piece
   535     // of chrome JS wants it.  The system call is specified as unable to fail.
   536     nsSystemInfo::gUserUmask = ::umask(0777);
   537     ::umask(nsSystemInfo::gUserUmask);
   538 #endif
   540     NS_LogInit();
   542     // Set up chromium libs
   543     NS_ASSERTION(!sExitManager && !sMessageLoop, "Bad logic!");
   545     if (!AtExitManager::AlreadyRegistered()) {
   546         sExitManager = new AtExitManager();
   547     }
   549     if (!MessageLoop::current()) {
   550         sMessageLoop = new MessageLoopForUI(MessageLoop::TYPE_MOZILLA_UI);
   551         sMessageLoop->set_thread_name("Gecko");
   552         // Set experimental values for main thread hangs:
   553         // 512ms for transient hangs and 8192ms for permanent hangs
   554         sMessageLoop->set_hang_timeouts(512, 8192);
   555     }
   557     if (XRE_GetProcessType() == GeckoProcessType_Default &&
   558         !BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)) {
   559         scoped_ptr<BrowserProcessSubThread> ioThread(
   560             new BrowserProcessSubThread(BrowserProcessSubThread::IO));
   562         base::Thread::Options options;
   563         options.message_loop_type = MessageLoop::TYPE_IO;
   564         if (NS_WARN_IF(!ioThread->StartWithOptions(options)))
   565             return NS_ERROR_FAILURE;
   567         sIOThread = ioThread.release();
   568     }
   570     // Establish the main thread here.
   571     rv = nsThreadManager::get()->Init();
   572     if (NS_WARN_IF(NS_FAILED(rv)))
   573         return rv;
   575     // Set up the timer globals/timer thread
   576     rv = nsTimerImpl::Startup();
   577     if (NS_WARN_IF(NS_FAILED(rv)))
   578         return rv;
   580 #ifndef ANDROID
   581     // If the locale hasn't already been setup by our embedder,
   582     // get us out of the "C" locale and into the system
   583     if (strcmp(setlocale(LC_ALL, nullptr), "C") == 0)
   584         setlocale(LC_ALL, "");
   585 #endif
   587 #if defined(XP_UNIX)
   588     NS_StartupNativeCharsetUtils();
   589 #endif
   591     NS_StartupLocalFile();
   593     StartupSpecialSystemDirectory();
   595     nsDirectoryService::RealInit();
   597     bool value;
   599     if (binDirectory)
   600     {
   601         rv = binDirectory->IsDirectory(&value);
   603         if (NS_SUCCEEDED(rv) && value) {
   604             nsDirectoryService::gService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, binDirectory);
   605         }
   606     }
   608     if (appFileLocationProvider) {
   609         rv = nsDirectoryService::gService->RegisterProvider(appFileLocationProvider);
   610         if (NS_FAILED(rv)) return rv;
   611     }
   613     nsCOMPtr<nsIFile> xpcomLib;
   615     nsDirectoryService::gService->Get(NS_GRE_DIR,
   616                                       NS_GET_IID(nsIFile),
   617                                       getter_AddRefs(xpcomLib));
   619     if (xpcomLib) {
   620         xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL));
   621         nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);
   622     }
   624     if (!mozilla::Omnijar::IsInitialized()) {
   625         mozilla::Omnijar::Init();
   626     }
   628     if ((sCommandLineWasInitialized = !CommandLine::IsInitialized())) {
   629 #ifdef OS_WIN
   630         CommandLine::Init(0, nullptr);
   631 #else
   632         nsCOMPtr<nsIFile> binaryFile;
   633         nsDirectoryService::gService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
   634                                           NS_GET_IID(nsIFile),
   635                                           getter_AddRefs(binaryFile));
   636         if (NS_WARN_IF(!binaryFile))
   637             return NS_ERROR_FAILURE;
   639         rv = binaryFile->AppendNative(NS_LITERAL_CSTRING("nonexistent-executable"));
   640         if (NS_WARN_IF(NS_FAILED(rv)))
   641             return rv;
   643         nsCString binaryPath;
   644         rv = binaryFile->GetNativePath(binaryPath);
   645         if (NS_WARN_IF(NS_FAILED(rv)))
   646             return rv;
   648         static char const *const argv = { strdup(binaryPath.get()) };
   649         CommandLine::Init(1, &argv);
   650 #endif
   651     }
   653     NS_ASSERTION(nsComponentManagerImpl::gComponentManager == nullptr, "CompMgr not null at init");
   655     // Create the Component/Service Manager
   656     nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl();
   657     NS_ADDREF(nsComponentManagerImpl::gComponentManager);
   659     // Global cycle collector initialization.
   660     if (!nsCycleCollector_init()) {
   661         return NS_ERROR_UNEXPECTED;
   662     }
   664     // And start it up for this thread too.
   665     nsCycleCollector_startup();
   667     // Register ICU memory functions.  This really shouldn't be necessary: the
   668     // JS engine should do this on its own inside JS_Init, and memory-reporting
   669     // code should call a JSAPI function to observe ICU memory usage.  But we
   670     // can't define the alloc/free functions in the JS engine, because it can't
   671     // depend on the XPCOM-based memory reporting goop.  So for now, we have
   672     // this oddness.
   673     mozilla::SetICUMemoryFunctions();
   675     // Do the same for libogg.
   676     ogg_set_mem_functions(OggReporter::CountingMalloc,
   677                           OggReporter::CountingCalloc,
   678                           OggReporter::CountingRealloc,
   679                           OggReporter::CountingFree);
   681 #if defined(MOZ_VPX) && !defined(MOZ_VPX_NO_MEM_REPORTING)
   682     // And for VPX.
   683     vpx_mem_set_functions(VPXReporter::CountingMalloc,
   684                           VPXReporter::CountingCalloc,
   685                           VPXReporter::CountingRealloc,
   686                           VPXReporter::CountingFree,
   687                           memcpy,
   688                           memset,
   689                           memmove);
   690 #endif
   692 #ifdef MOZ_WEBM
   693     // And for libnestegg.
   694     nestegg_set_halloc_func(NesteggReporter::CountingRealloc);
   695 #endif
   697     // Initialize the JS engine.
   698     if (!JS_Init()) {
   699         NS_RUNTIMEABORT("JS_Init failed");
   700     }
   702     rv = nsComponentManagerImpl::gComponentManager->Init();
   703     if (NS_FAILED(rv))
   704     {
   705         NS_RELEASE(nsComponentManagerImpl::gComponentManager);
   706         return rv;
   707     }
   709     if (result) {
   710         NS_ADDREF(*result = nsComponentManagerImpl::gComponentManager);
   711     }
   713     // The iimanager constructor searches and registers XPT files.
   714     // (We trigger the singleton's lazy construction here to make that happen.)
   715     (void) XPTInterfaceInfoManager::GetSingleton();
   717     // After autoreg, but before we actually instantiate any components,
   718     // add any services listed in the "xpcom-directory-providers" category
   719     // to the directory service.
   720     nsDirectoryService::gService->RegisterCategoryProviders();
   722     // Force layout to spin up so that nsContentUtils is available for cx stack
   723     // munging.
   724     nsCOMPtr<nsISupports> componentLoader = do_GetService("@mozilla.org/moz/jsloader;1");
   726     mozilla::scache::StartupCache::GetSingleton();
   727     mozilla::AvailableMemoryTracker::Activate();
   729     // Notify observers of xpcom autoregistration start
   730     NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_CATEGORY,
   731                                   nullptr,
   732                                   NS_XPCOM_STARTUP_OBSERVER_ID);
   733 #ifdef XP_WIN
   734     CreateAnonTempFileRemover();
   735 #endif
   737     // We only want the SystemMemoryReporter running in one process, because it
   738     // profiles the entire system.  The main process is the obvious place for
   739     // it.
   740     if (XRE_GetProcessType() == GeckoProcessType_Default) {
   741         mozilla::SystemMemoryReporter::Init();
   742     }
   744     // The memory reporter manager is up and running -- register our reporters.
   745     RegisterStrongMemoryReporter(new ICUReporter());
   746     RegisterStrongMemoryReporter(new OggReporter());
   747 #ifdef MOZ_VPX
   748     RegisterStrongMemoryReporter(new VPXReporter());
   749 #endif
   750 #ifdef MOZ_WEBM
   751     RegisterStrongMemoryReporter(new NesteggReporter());
   752 #endif
   754     mozilla::Telemetry::Init();
   756     mozilla::HangMonitor::Startup();
   757     mozilla::BackgroundHangMonitor::Startup();
   759     const MessageLoop* const loop = MessageLoop::current();
   760     sMainHangMonitor = new mozilla::BackgroundHangMonitor(
   761         loop->thread_name().c_str(),
   762         loop->transient_hang_timeout(),
   763         loop->permanent_hang_timeout());
   765 #ifdef MOZ_VISUAL_EVENT_TRACER
   766     mozilla::eventtracer::Init();
   767 #endif
   769     // Start watching the javascript.default_locale pref.
   770     StartWatchingDefaultLocalePref();
   771     return NS_OK;
   772 }
   775 //
   776 // NS_ShutdownXPCOM()
   777 //
   778 // The shutdown sequence for xpcom would be
   779 //
   780 // - Notify "xpcom-shutdown" for modules to release primary (root) references
   781 // - Shutdown XPCOM timers
   782 // - Notify "xpcom-shutdown-threads" for thread joins
   783 // - Shutdown the event queues
   784 // - Release the Global Service Manager
   785 //   - Release all service instances held by the global service manager
   786 //   - Release the Global Service Manager itself
   787 // - Release the Component Manager
   788 //   - Release all factories cached by the Component Manager
   789 //   - Notify module loaders to shut down
   790 //   - Unload Libraries
   791 //   - Release Contractid Cache held by Component Manager
   792 //   - Release dll abstraction held by Component Manager
   793 //   - Release the Registry held by Component Manager
   794 //   - Finally, release the component manager itself
   795 //
   796 EXPORT_XPCOM_API(nsresult)
   797 NS_ShutdownXPCOM(nsIServiceManager* servMgr)
   798 {
   799     return mozilla::ShutdownXPCOM(servMgr);
   800 }
   802 namespace mozilla {
   804 void
   805 SetICUMemoryFunctions()
   806 {
   807     static bool sICUReporterInitialized = false;
   808     if (!sICUReporterInitialized) {
   809         if (!JS_SetICUMemoryFunctions(ICUReporter::Alloc, ICUReporter::Realloc,
   810                                       ICUReporter::Free)) {
   811             NS_RUNTIMEABORT("JS_SetICUMemoryFunctions failed.");
   812         }
   813         sICUReporterInitialized = true;
   814     }
   815 }
   817 nsresult
   818 ShutdownXPCOM(nsIServiceManager* servMgr)
   819 {
   820     // Make sure the hang monitor is enabled for shutdown.
   821     HangMonitor::NotifyActivity();
   823     if (!NS_IsMainThread()) {
   824         NS_RUNTIMEABORT("Shutdown on wrong thread");
   825     }
   827     nsresult rv;
   828     nsCOMPtr<nsISimpleEnumerator> moduleLoaders;
   830     // Notify observers of xpcom shutting down
   831     {
   832         // Block it so that the COMPtr will get deleted before we hit
   833         // servicemanager shutdown
   835         nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
   836         if (NS_WARN_IF(!thread))
   837             return NS_ERROR_UNEXPECTED;
   839         nsRefPtr<nsObserverService> observerService;
   840         CallGetService("@mozilla.org/observer-service;1",
   841                        (nsObserverService**) getter_AddRefs(observerService));
   843         if (observerService)
   844         {
   845             (void) observerService->
   846                 NotifyObservers(nullptr, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID,
   847                                 nullptr);
   849             nsCOMPtr<nsIServiceManager> mgr;
   850             rv = NS_GetServiceManager(getter_AddRefs(mgr));
   851             if (NS_SUCCEEDED(rv))
   852             {
   853                 (void) observerService->
   854                     NotifyObservers(mgr, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
   855                                     nullptr);
   856             }
   857         }
   859         // This must happen after the shutdown of media and widgets, which
   860         // are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification.
   861         layers::ImageBridgeChild::ShutDown();
   863         NS_ProcessPendingEvents(thread);
   864         mozilla::scache::StartupCache::DeleteSingleton();
   865         if (observerService)
   866             (void) observerService->
   867                 NotifyObservers(nullptr, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID,
   868                                 nullptr);
   870         layers::CompositorParent::ShutDown();
   872         gXPCOMThreadsShutDown = true;
   873         NS_ProcessPendingEvents(thread);
   875         // Shutdown the timer thread and all timers that might still be alive before
   876         // shutting down the component manager
   877         nsTimerImpl::Shutdown();
   879         NS_ProcessPendingEvents(thread);
   881         // Shutdown all remaining threads.  This method does not return until
   882         // all threads created using the thread manager (with the exception of
   883         // the main thread) have exited.
   884         nsThreadManager::get()->Shutdown();
   886         NS_ProcessPendingEvents(thread);
   888         HangMonitor::NotifyActivity();
   890         // Late-write checks needs to find the profile directory, so it has to
   891         // be initialized before mozilla::services::Shutdown or (because of
   892         // xpcshell tests replacing the service) modules being unloaded.
   893         mozilla::InitLateWriteChecks();
   895         // We save the "xpcom-shutdown-loaders" observers to notify after
   896         // the observerservice is gone.
   897         if (observerService) {
   898             observerService->
   899                 EnumerateObservers(NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID,
   900                                    getter_AddRefs(moduleLoaders));
   902             observerService->Shutdown();
   903         }
   904     }
   906     // Free ClearOnShutdown()'ed smart pointers.  This needs to happen *after*
   907     // we've finished notifying observers of XPCOM shutdown, because shutdown
   908     // observers themselves might call ClearOnShutdown().
   909     mozilla::KillClearOnShutdown();
   911     // XPCOM is officially in shutdown mode NOW
   912     // Set this only after the observers have been notified as this
   913     // will cause servicemanager to become inaccessible.
   914     mozilla::services::Shutdown();
   916 #ifdef DEBUG_dougt
   917     fprintf(stderr, "* * * * XPCOM shutdown. Access will be denied * * * * \n");
   918 #endif
   919     // We may have AddRef'd for the caller of NS_InitXPCOM, so release it
   920     // here again:
   921     NS_IF_RELEASE(servMgr);
   923     // Shutdown global servicemanager
   924     if (nsComponentManagerImpl::gComponentManager) {
   925         nsComponentManagerImpl::gComponentManager->FreeServices();
   926     }
   928     // Release the directory service
   929     NS_IF_RELEASE(nsDirectoryService::gService);
   931     if (moduleLoaders) {
   932         bool more;
   933         nsCOMPtr<nsISupports> el;
   934         while (NS_SUCCEEDED(moduleLoaders->HasMoreElements(&more)) &&
   935                more) {
   936             moduleLoaders->GetNext(getter_AddRefs(el));
   938             // Don't worry about weak-reference observers here: there is
   939             // no reason for weak-ref observers to register for
   940             // xpcom-shutdown-loaders
   942             // FIXME: This can cause harmless writes from sqlite committing
   943             // log files. We have to ignore them before we can move
   944             // the mozilla::PoisonWrite call before this point. See bug
   945             // 834945 for the details.
   946             nsCOMPtr<nsIObserver> obs(do_QueryInterface(el));
   947             if (obs)
   948                 (void) obs->Observe(nullptr,
   949                                     NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID,
   950                                     nullptr);
   951         }
   953         moduleLoaders = nullptr;
   954     }
   956     nsCycleCollector_shutdown();
   958     PROFILER_MARKER("Shutdown xpcom");
   959     // If we are doing any shutdown checks, poison writes.
   960     if (gShutdownChecks != SCM_NOTHING) {
   961 #ifdef XP_MACOSX
   962         mozilla::OnlyReportDirtyWrites();
   963 #endif /* XP_MACOSX */
   964         mozilla::BeginLateWriteChecks();
   965     }
   967     // Shutdown nsLocalFile string conversion
   968     NS_ShutdownLocalFile();
   969 #ifdef XP_UNIX
   970     NS_ShutdownNativeCharsetUtils();
   971 #endif
   973     // Shutdown xpcom. This will release all loaders and cause others holding
   974     // a refcount to the component manager to release it.
   975     if (nsComponentManagerImpl::gComponentManager) {
   976         rv = (nsComponentManagerImpl::gComponentManager)->Shutdown();
   977         NS_ASSERTION(NS_SUCCEEDED(rv), "Component Manager shutdown failed.");
   978     } else {
   979         NS_WARNING("Component Manager was never created ...");
   980     }
   982 #ifdef MOZ_ENABLE_PROFILER_SPS
   983     // In optimized builds we don't do shutdown collections by default, so
   984     // uncollected (garbage) objects may keep the nsXPConnect singleton alive,
   985     // and its XPCJSRuntime along with it. However, we still destroy various
   986     // bits of state in JS_ShutDown(), so we need to make sure the profiler
   987     // can't access them when it shuts down. This call nulls out the
   988     // JS pseudo-stack's internal reference to the main thread JSRuntime,
   989     // duplicating the call in XPCJSRuntime::~XPCJSRuntime() in case that
   990     // never fired.
   991     if (PseudoStack *stack = mozilla_get_pseudo_stack()) {
   992         stack->sampleRuntime(nullptr);
   993     }
   994 #endif
   996     // Shut down the JS engine.
   997     JS_ShutDown();
   999     // Release our own singletons
  1000     // Do this _after_ shutting down the component manager, because the
  1001     // JS component loader will use XPConnect to call nsIModule::canUnload,
  1002     // and that will spin up the InterfaceInfoManager again -- bad mojo
  1003     XPTInterfaceInfoManager::FreeInterfaceInfoManager();
  1005     // Finally, release the component manager last because it unloads the
  1006     // libraries:
  1007     if (nsComponentManagerImpl::gComponentManager) {
  1008       nsrefcnt cnt;
  1009       NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt);
  1010       NS_ASSERTION(cnt == 0, "Component Manager being held past XPCOM shutdown.");
  1012     nsComponentManagerImpl::gComponentManager = nullptr;
  1013     nsCategoryManager::Destroy();
  1015     NS_PurgeAtomTable();
  1017     NS_IF_RELEASE(gDebug);
  1019     if (sIOThread) {
  1020         delete sIOThread;
  1021         sIOThread = nullptr;
  1023     if (sMessageLoop) {
  1024         delete sMessageLoop;
  1025         sMessageLoop = nullptr;
  1027     if (sCommandLineWasInitialized) {
  1028         CommandLine::Terminate();
  1029         sCommandLineWasInitialized = false;
  1031     if (sExitManager) {
  1032         delete sExitManager;
  1033         sExitManager = nullptr;
  1036     StopWatchingDefaultLocalePref();
  1038     Omnijar::CleanUp();
  1040     HangMonitor::Shutdown();
  1042     if (sMainHangMonitor) {
  1043         delete sMainHangMonitor;
  1044         sMainHangMonitor = nullptr;
  1046     BackgroundHangMonitor::Shutdown();
  1048 #ifdef MOZ_VISUAL_EVENT_TRACER
  1049     eventtracer::Shutdown();
  1050 #endif
  1052     profiler_shutdown();
  1054     NS_LogTerm();
  1056     return NS_OK;
  1059 } // namespace mozilla

mercurial