Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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.");
1011 }
1012 nsComponentManagerImpl::gComponentManager = nullptr;
1013 nsCategoryManager::Destroy();
1015 NS_PurgeAtomTable();
1017 NS_IF_RELEASE(gDebug);
1019 if (sIOThread) {
1020 delete sIOThread;
1021 sIOThread = nullptr;
1022 }
1023 if (sMessageLoop) {
1024 delete sMessageLoop;
1025 sMessageLoop = nullptr;
1026 }
1027 if (sCommandLineWasInitialized) {
1028 CommandLine::Terminate();
1029 sCommandLineWasInitialized = false;
1030 }
1031 if (sExitManager) {
1032 delete sExitManager;
1033 sExitManager = nullptr;
1034 }
1036 StopWatchingDefaultLocalePref();
1038 Omnijar::CleanUp();
1040 HangMonitor::Shutdown();
1042 if (sMainHangMonitor) {
1043 delete sMainHangMonitor;
1044 sMainHangMonitor = nullptr;
1045 }
1046 BackgroundHangMonitor::Shutdown();
1048 #ifdef MOZ_VISUAL_EVENT_TRACER
1049 eventtracer::Shutdown();
1050 #endif
1052 profiler_shutdown();
1054 NS_LogTerm();
1056 return NS_OK;
1057 }
1059 } // namespace mozilla