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