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