xpcom/build/nsXPComInit.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial