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 : /* ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is mozilla.org code.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Netscape Communications Corporation.
20 : * Portions created by the Initial Developer are Copyright (C) 1998
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Benjamin Smedberg <benjamin@smedbergs.us>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either of the GNU General Public License Version 2 or later (the "GPL"),
28 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #include "base/basictypes.h"
41 :
42 : #include "mozilla/XPCOM.h"
43 : #include "nsXULAppAPI.h"
44 :
45 : #include "nsXPCOMPrivate.h"
46 : #include "nsXPCOMCIDInternal.h"
47 :
48 : #include "nsStaticComponents.h"
49 : #include "prlink.h"
50 :
51 : #include "nsObserverList.h"
52 : #include "nsObserverService.h"
53 : #include "nsProperties.h"
54 : #include "nsPersistentProperties.h"
55 : #include "nsScriptableInputStream.h"
56 : #include "nsBinaryStream.h"
57 : #include "nsStorageStream.h"
58 : #include "nsPipe.h"
59 : #include "nsScriptableBase64Encoder.h"
60 :
61 : #include "nsMemoryImpl.h"
62 : #include "nsDebugImpl.h"
63 : #include "nsTraceRefcntImpl.h"
64 : #include "nsErrorService.h"
65 : #include "nsByteBuffer.h"
66 :
67 : #include "nsSupportsArray.h"
68 : #include "nsArray.h"
69 : #include "nsINIParserImpl.h"
70 : #include "nsSupportsPrimitives.h"
71 : #include "nsConsoleService.h"
72 : #include "nsExceptionService.h"
73 :
74 : #include "nsComponentManager.h"
75 : #include "nsCategoryManagerUtils.h"
76 : #include "nsIServiceManager.h"
77 :
78 : #include "nsThreadManager.h"
79 : #include "nsThreadPool.h"
80 :
81 : #include "xptinfo.h"
82 : #include "nsIInterfaceInfoManager.h"
83 : #include "xptiprivate.h"
84 :
85 : #include "nsTimerImpl.h"
86 : #include "TimerThread.h"
87 :
88 : #include "nsThread.h"
89 : #include "nsProcess.h"
90 : #include "nsEnvironment.h"
91 : #include "nsVersionComparatorImpl.h"
92 :
93 : #include "nsILocalFile.h"
94 : #include "nsLocalFile.h"
95 : #if defined(XP_UNIX) || defined(XP_OS2)
96 : #include "nsNativeCharsetUtils.h"
97 : #endif
98 : #include "nsDirectoryService.h"
99 : #include "nsDirectoryServiceDefs.h"
100 : #include "nsCategoryManager.h"
101 : #include "nsICategoryManager.h"
102 : #include "nsMultiplexInputStream.h"
103 :
104 : #include "nsStringStream.h"
105 : extern nsresult nsStringInputStreamConstructor(nsISupports *, REFNSIID, void **);
106 :
107 : #include "nsAtomService.h"
108 : #include "nsAtomTable.h"
109 : #include "nsTraceRefcnt.h"
110 :
111 : #include "nsHashPropertyBag.h"
112 :
113 : #include "nsUnicharInputStream.h"
114 : #include "nsVariant.h"
115 :
116 : #include "nsUUIDGenerator.h"
117 :
118 : #include "nsIOUtil.h"
119 :
120 : #include "SpecialSystemDirectory.h"
121 :
122 : #if defined(XP_WIN)
123 : #include "nsWindowsRegKey.h"
124 : #endif
125 :
126 : #ifdef MOZ_WIDGET_COCOA
127 : #include "nsMacUtilsImpl.h"
128 : #endif
129 :
130 : #include "nsSystemInfo.h"
131 : #include "nsMemoryReporterManager.h"
132 :
133 : #include <locale.h>
134 : #include "mozilla/Services.h"
135 : #include "mozilla/FunctionTimer.h"
136 : #include "mozilla/Omnijar.h"
137 : #include "mozilla/HangMonitor.h"
138 : #include "mozilla/Telemetry.h"
139 :
140 : #include "nsChromeRegistry.h"
141 : #include "nsChromeProtocolHandler.h"
142 :
143 : #include "mozilla/scache/StartupCache.h"
144 :
145 : #include "base/at_exit.h"
146 : #include "base/command_line.h"
147 : #include "base/message_loop.h"
148 :
149 : #include "mozilla/ipc/BrowserProcessSubThread.h"
150 : #include "mozilla/MapsMemoryReporter.h"
151 : #include "mozilla/AvailableMemoryTracker.h"
152 : #include "mozilla/ClearOnShutdown.h"
153 :
154 : using base::AtExitManager;
155 : using mozilla::ipc::BrowserProcessSubThread;
156 :
157 : namespace {
158 :
159 : static AtExitManager* sExitManager;
160 : static MessageLoop* sMessageLoop;
161 : static bool sCommandLineWasInitialized;
162 : static BrowserProcessSubThread* sIOThread;
163 :
164 : } /* anonymous namespace */
165 :
166 : // Registry Factory creation function defined in nsRegistry.cpp
167 : // We hook into this function locally to create and register the registry
168 : // Since noone outside xpcom needs to know about this and nsRegistry.cpp
169 : // does not have a local include file, we are putting this definition
170 : // here rather than in nsIRegistry.h
171 : extern nsresult NS_RegistryGetFactory(nsIFactory** aFactory);
172 : extern nsresult NS_CategoryManagerGetFactory( nsIFactory** );
173 :
174 : #ifdef XP_WIN
175 : extern nsresult ScheduleMediaCacheRemover();
176 : #endif
177 :
178 2038 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsProcess)
179 :
180 0 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsIDImpl)
181 68950 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsStringImpl)
182 466 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsCStringImpl)
183 948 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRBoolImpl)
184 2 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint8Impl)
185 2 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint16Impl)
186 28 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint32Impl)
187 2 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint64Impl)
188 0 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRTimeImpl)
189 0 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsCharImpl)
190 2 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt16Impl)
191 2 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt32Impl)
192 66 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt64Impl)
193 2 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsFloatImpl)
194 2 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsDoubleImpl)
195 0 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsVoidImpl)
196 0 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsInterfacePointerImpl)
197 :
198 2780 : NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsConsoleService, Init)
199 0 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsAtomService)
200 2782 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsExceptionService)
201 24608 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimerImpl)
202 16506 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryOutputStream)
203 34212 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryInputStream)
204 460 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsStorageStream)
205 366 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsVersionComparatorImpl)
206 0 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptableBase64Encoder)
207 :
208 83364 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsVariant)
209 :
210 1372 : NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHashPropertyBag, Init)
211 :
212 16 : NS_GENERIC_AGGREGATED_CONSTRUCTOR_INIT(nsProperties, Init)
213 :
214 2808 : NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUUIDGenerator, Init)
215 :
216 : #ifdef MOZ_WIDGET_COCOA
217 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacUtilsImpl)
218 : #endif
219 :
220 460 : NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemInfo, Init)
221 :
222 2838 : NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsMemoryReporterManager, Init)
223 :
224 50 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsIOUtil)
225 :
226 : static nsresult
227 1420 : nsThreadManagerGetSingleton(nsISupports* outer,
228 : const nsIID& aIID,
229 : void* *aInstancePtr)
230 : {
231 1420 : NS_ASSERTION(aInstancePtr, "null outptr");
232 1420 : NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION);
233 :
234 1420 : return nsThreadManager::get()->QueryInterface(aIID, aInstancePtr);
235 : }
236 :
237 3120 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsThreadPool)
238 :
239 : static nsresult
240 1404 : nsXPTIInterfaceInfoManagerGetSingleton(nsISupports* outer,
241 : const nsIID& aIID,
242 : void* *aInstancePtr)
243 : {
244 1404 : NS_ASSERTION(aInstancePtr, "null outptr");
245 1404 : NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION);
246 :
247 : nsCOMPtr<nsIInterfaceInfoManager> iim
248 2808 : (xptiInterfaceInfoManager::GetSingleton());
249 1404 : if (!iim)
250 0 : return NS_ERROR_FAILURE;
251 :
252 1404 : return iim->QueryInterface(aIID, aInstancePtr);
253 : }
254 :
255 : nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = NULL;
256 : bool gXPCOMShuttingDown = false;
257 :
258 : static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
259 : static NS_DEFINE_CID(kINIParserFactoryCID, NS_INIPARSERFACTORY_CID);
260 : static NS_DEFINE_CID(kSimpleUnicharStreamFactoryCID, NS_SIMPLE_UNICHAR_STREAM_FACTORY_CID);
261 :
262 : NS_DEFINE_NAMED_CID(NS_CHROMEREGISTRY_CID);
263 : NS_DEFINE_NAMED_CID(NS_CHROMEPROTOCOLHANDLER_CID);
264 :
265 1419 : NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsChromeRegistry,
266 1419 : nsChromeRegistry::GetSingleton)
267 2838 : NS_GENERIC_FACTORY_CONSTRUCTOR(nsChromeProtocolHandler)
268 :
269 : #define NS_PERSISTENTPROPERTIES_CID NS_IPERSISTENTPROPERTIES_CID /* sigh */
270 :
271 : static already_AddRefed<nsIFactory>
272 147 : CreateINIParserFactory(const mozilla::Module& module,
273 : const mozilla::Module::CIDEntry& entry)
274 : {
275 147 : nsIFactory* f = new nsINIParserFactory();
276 147 : f->AddRef();
277 147 : return f;
278 : }
279 :
280 : static already_AddRefed<nsIFactory>
281 0 : CreateUnicharStreamFactory(const mozilla::Module& module,
282 : const mozilla::Module::CIDEntry& entry)
283 : {
284 0 : return nsSimpleUnicharStreamFactory::GetInstance();
285 : }
286 :
287 : #define COMPONENT(NAME, Ctor) static NS_DEFINE_CID(kNS_##NAME##_CID, NS_##NAME##_CID);
288 : #include "XPCOMModule.inc"
289 : #undef COMPONENT
290 :
291 : #define COMPONENT(NAME, Ctor) { &kNS_##NAME##_CID, false, NULL, Ctor },
292 : const mozilla::Module::CIDEntry kXPCOMCIDEntries[] = {
293 : { &kComponentManagerCID, true, NULL, nsComponentManagerImpl::Create },
294 : { &kINIParserFactoryCID, false, CreateINIParserFactory },
295 : { &kSimpleUnicharStreamFactoryCID, false, CreateUnicharStreamFactory },
296 : #include "XPCOMModule.inc"
297 : { &kNS_CHROMEREGISTRY_CID, false, NULL, nsChromeRegistryConstructor },
298 : { &kNS_CHROMEPROTOCOLHANDLER_CID, false, NULL, nsChromeProtocolHandlerConstructor },
299 : { NULL }
300 : };
301 : #undef COMPONENT
302 :
303 : #define COMPONENT(NAME, Ctor) { NS_##NAME##_CONTRACTID, &kNS_##NAME##_CID },
304 : const mozilla::Module::ContractIDEntry kXPCOMContracts[] = {
305 : #include "XPCOMModule.inc"
306 : { NS_CHROMEREGISTRY_CONTRACTID, &kNS_CHROMEREGISTRY_CID },
307 : { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "chrome", &kNS_CHROMEPROTOCOLHANDLER_CID },
308 : { NS_INIPARSERFACTORY_CONTRACTID, &kINIParserFactoryCID },
309 : { NULL }
310 : };
311 : #undef COMPONENT
312 :
313 : const mozilla::Module kXPCOMModule = { mozilla::Module::kVersion, kXPCOMCIDEntries, kXPCOMContracts };
314 :
315 : // gDebug will be freed during shutdown.
316 : static nsIDebug* gDebug = nsnull;
317 :
318 : EXPORT_XPCOM_API(nsresult)
319 0 : NS_GetDebug(nsIDebug** result)
320 : {
321 : return nsDebugImpl::Create(nsnull,
322 : NS_GET_IID(nsIDebug),
323 0 : (void**) result);
324 : }
325 :
326 : EXPORT_XPCOM_API(nsresult)
327 0 : NS_GetTraceRefcnt(nsITraceRefcnt** result)
328 : {
329 : return nsTraceRefcntImpl::Create(nsnull,
330 : NS_GET_IID(nsITraceRefcnt),
331 0 : (void**) result);
332 : }
333 :
334 : EXPORT_XPCOM_API(nsresult)
335 0 : NS_InitXPCOM(nsIServiceManager* *result,
336 : nsIFile* binDirectory)
337 : {
338 0 : return NS_InitXPCOM2(result, binDirectory, nsnull);
339 : }
340 :
341 : EXPORT_XPCOM_API(nsresult)
342 1419 : NS_InitXPCOM2(nsIServiceManager* *result,
343 : nsIFile* binDirectory,
344 : nsIDirectoryServiceProvider* appFileLocationProvider)
345 : {
346 : NS_TIME_FUNCTION;
347 :
348 1419 : nsresult rv = NS_OK;
349 :
350 : // We are not shutting down
351 1419 : gXPCOMShuttingDown = false;
352 :
353 : NS_TIME_FUNCTION_MARK("Next: log init");
354 :
355 1419 : NS_LogInit();
356 :
357 : NS_TIME_FUNCTION_MARK("Next: IPC init");
358 :
359 : // Set up chromium libs
360 1419 : NS_ASSERTION(!sExitManager && !sMessageLoop, "Bad logic!");
361 :
362 1419 : if (!AtExitManager::AlreadyRegistered()) {
363 1419 : sExitManager = new AtExitManager();
364 1419 : NS_ENSURE_STATE(sExitManager);
365 : }
366 :
367 1419 : if (!MessageLoop::current()) {
368 1419 : sMessageLoop = new MessageLoopForUI(MessageLoop::TYPE_MOZILLA_UI);
369 1419 : NS_ENSURE_STATE(sMessageLoop);
370 : }
371 :
372 2838 : if (XRE_GetProcessType() == GeckoProcessType_Default &&
373 1419 : !BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)) {
374 : scoped_ptr<BrowserProcessSubThread> ioThread(
375 2838 : new BrowserProcessSubThread(BrowserProcessSubThread::IO));
376 1419 : NS_ENSURE_TRUE(ioThread.get(), NS_ERROR_OUT_OF_MEMORY);
377 :
378 1419 : base::Thread::Options options;
379 1419 : options.message_loop_type = MessageLoop::TYPE_IO;
380 1419 : NS_ENSURE_TRUE(ioThread->StartWithOptions(options), NS_ERROR_FAILURE);
381 :
382 2838 : sIOThread = ioThread.release();
383 : }
384 :
385 : NS_TIME_FUNCTION_MARK("Next: thread manager init");
386 :
387 : // Establish the main thread here.
388 1419 : rv = nsThreadManager::get()->Init();
389 1419 : if (NS_FAILED(rv)) return rv;
390 :
391 : NS_TIME_FUNCTION_MARK("Next: timer startup");
392 :
393 : // Set up the timer globals/timer thread
394 1419 : rv = nsTimerImpl::Startup();
395 1419 : NS_ENSURE_SUCCESS(rv, rv);
396 :
397 : #ifndef ANDROID
398 : NS_TIME_FUNCTION_MARK("Next: setlocale");
399 :
400 : // If the locale hasn't already been setup by our embedder,
401 : // get us out of the "C" locale and into the system
402 1419 : if (strcmp(setlocale(LC_ALL, NULL), "C") == 0)
403 1419 : setlocale(LC_ALL, "");
404 : #endif
405 :
406 : #if defined(XP_UNIX) || defined(XP_OS2)
407 : NS_TIME_FUNCTION_MARK("Next: startup native charset utils");
408 :
409 1419 : NS_StartupNativeCharsetUtils();
410 : #endif
411 :
412 : NS_TIME_FUNCTION_MARK("Next: startup local file");
413 :
414 1419 : NS_StartupLocalFile();
415 :
416 1419 : StartupSpecialSystemDirectory();
417 :
418 1419 : rv = nsDirectoryService::RealInit();
419 1419 : if (NS_FAILED(rv))
420 0 : return rv;
421 :
422 : bool value;
423 :
424 1419 : if (binDirectory)
425 : {
426 1387 : rv = binDirectory->IsDirectory(&value);
427 :
428 1387 : if (NS_SUCCEEDED(rv) && value) {
429 1387 : nsDirectoryService::gService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, binDirectory);
430 : }
431 : }
432 :
433 1419 : if (appFileLocationProvider) {
434 1417 : rv = nsDirectoryService::gService->RegisterProvider(appFileLocationProvider);
435 1417 : if (NS_FAILED(rv)) return rv;
436 : }
437 :
438 2838 : nsCOMPtr<nsIFile> xpcomLib;
439 :
440 : nsDirectoryService::gService->Get(NS_GRE_DIR,
441 : NS_GET_IID(nsIFile),
442 1419 : getter_AddRefs(xpcomLib));
443 :
444 1419 : if (xpcomLib) {
445 1419 : xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL));
446 1419 : nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);
447 : }
448 :
449 : NS_TIME_FUNCTION_MARK("Next: Omnijar init");
450 :
451 1419 : if (!mozilla::Omnijar::IsInitialized()) {
452 1419 : mozilla::Omnijar::Init();
453 : }
454 :
455 1419 : if ((sCommandLineWasInitialized = !CommandLine::IsInitialized())) {
456 : NS_TIME_FUNCTION_MARK("Next: IPC command line init");
457 :
458 : #ifdef OS_WIN
459 : CommandLine::Init(0, nsnull);
460 : #else
461 2838 : nsCOMPtr<nsIFile> binaryFile;
462 : nsDirectoryService::gService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
463 : NS_GET_IID(nsIFile),
464 1419 : getter_AddRefs(binaryFile));
465 1419 : NS_ENSURE_STATE(binaryFile);
466 :
467 1419 : rv = binaryFile->AppendNative(NS_LITERAL_CSTRING("nonexistent-executable"));
468 1419 : NS_ENSURE_SUCCESS(rv, rv);
469 :
470 2838 : nsCString binaryPath;
471 1419 : rv = binaryFile->GetNativePath(binaryPath);
472 1419 : NS_ENSURE_SUCCESS(rv, rv);
473 :
474 1419 : static char const *const argv = { strdup(binaryPath.get()) };
475 2838 : CommandLine::Init(1, &argv);
476 : #endif
477 : }
478 :
479 1419 : NS_ASSERTION(nsComponentManagerImpl::gComponentManager == NULL, "CompMgr not null at init");
480 :
481 : NS_TIME_FUNCTION_MARK("Next: component manager init");
482 :
483 : // Create the Component/Service Manager
484 1419 : nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl();
485 1419 : NS_ADDREF(nsComponentManagerImpl::gComponentManager);
486 :
487 1419 : rv = nsCycleCollector_startup();
488 1419 : if (NS_FAILED(rv)) return rv;
489 :
490 1419 : rv = nsComponentManagerImpl::gComponentManager->Init();
491 1419 : if (NS_FAILED(rv))
492 : {
493 0 : NS_RELEASE(nsComponentManagerImpl::gComponentManager);
494 0 : return rv;
495 : }
496 :
497 1419 : if (result) {
498 1417 : NS_ADDREF(*result = nsComponentManagerImpl::gComponentManager);
499 : }
500 :
501 : NS_TIME_FUNCTION_MARK("Next: cycle collector startup");
502 :
503 : NS_TIME_FUNCTION_MARK("Next: interface info manager init");
504 :
505 : // The iimanager constructor searches and registers XPT files.
506 : // (We trigger the singleton's lazy construction here to make that happen.)
507 1419 : (void) xptiInterfaceInfoManager::GetSingleton();
508 :
509 : NS_TIME_FUNCTION_MARK("Next: register category providers");
510 :
511 : // After autoreg, but before we actually instantiate any components,
512 : // add any services listed in the "xpcom-directory-providers" category
513 : // to the directory service.
514 1419 : nsDirectoryService::gService->RegisterCategoryProviders();
515 :
516 1419 : mozilla::scache::StartupCache::GetSingleton();
517 1419 : mozilla::AvailableMemoryTracker::Init();
518 :
519 : NS_TIME_FUNCTION_MARK("Next: create services from category");
520 :
521 : // Notify observers of xpcom autoregistration start
522 : NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_CATEGORY,
523 : nsnull,
524 1419 : NS_XPCOM_STARTUP_OBSERVER_ID);
525 : #ifdef XP_WIN
526 : ScheduleMediaCacheRemover();
527 : #endif
528 :
529 1419 : mozilla::MapsMemoryReporter::Init();
530 :
531 1419 : mozilla::HangMonitor::Startup();
532 :
533 1419 : mozilla::Telemetry::Init();
534 :
535 1419 : return NS_OK;
536 : }
537 :
538 :
539 : //
540 : // NS_ShutdownXPCOM()
541 : //
542 : // The shutdown sequence for xpcom would be
543 : //
544 : // - Notify "xpcom-shutdown" for modules to release primary (root) references
545 : // - Shutdown XPCOM timers
546 : // - Notify "xpcom-shutdown-threads" for thread joins
547 : // - Shutdown the event queues
548 : // - Release the Global Service Manager
549 : // - Release all service instances held by the global service manager
550 : // - Release the Global Service Manager itself
551 : // - Release the Component Manager
552 : // - Release all factories cached by the Component Manager
553 : // - Notify module loaders to shut down
554 : // - Unload Libraries
555 : // - Release Contractid Cache held by Component Manager
556 : // - Release dll abstraction held by Component Manager
557 : // - Release the Registry held by Component Manager
558 : // - Finally, release the component manager itself
559 : //
560 : EXPORT_XPCOM_API(nsresult)
561 1419 : NS_ShutdownXPCOM(nsIServiceManager* servMgr)
562 : {
563 1419 : return mozilla::ShutdownXPCOM(servMgr);
564 : }
565 :
566 : namespace mozilla {
567 :
568 : nsresult
569 1419 : ShutdownXPCOM(nsIServiceManager* servMgr)
570 : {
571 : // Make sure the hang monitor is enabled for shutdown.
572 1419 : HangMonitor::NotifyActivity();
573 :
574 1419 : NS_ENSURE_STATE(NS_IsMainThread());
575 :
576 : nsresult rv;
577 2838 : nsCOMPtr<nsISimpleEnumerator> moduleLoaders;
578 :
579 : // Notify observers of xpcom shutting down
580 : {
581 : // Block it so that the COMPtr will get deleted before we hit
582 : // servicemanager shutdown
583 :
584 2838 : nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
585 1419 : NS_ENSURE_STATE(thread);
586 :
587 4257 : nsRefPtr<nsObserverService> observerService;
588 : CallGetService("@mozilla.org/observer-service;1",
589 1419 : (nsObserverService**) getter_AddRefs(observerService));
590 :
591 1419 : if (observerService)
592 : {
593 1419 : (void) observerService->
594 : NotifyObservers(nsnull, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID,
595 1419 : nsnull);
596 :
597 2838 : nsCOMPtr<nsIServiceManager> mgr;
598 1419 : rv = NS_GetServiceManager(getter_AddRefs(mgr));
599 1419 : if (NS_SUCCEEDED(rv))
600 : {
601 1419 : (void) observerService->
602 : NotifyObservers(mgr, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
603 1419 : nsnull);
604 : }
605 : }
606 :
607 1419 : NS_ProcessPendingEvents(thread);
608 1419 : mozilla::scache::StartupCache::DeleteSingleton();
609 1419 : if (observerService)
610 1419 : (void) observerService->
611 : NotifyObservers(nsnull, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID,
612 1419 : nsnull);
613 :
614 1419 : nsCycleCollector_shutdownThreads();
615 :
616 1419 : NS_ProcessPendingEvents(thread);
617 :
618 : // Shutdown the timer thread and all timers that might still be alive before
619 : // shutting down the component manager
620 1419 : nsTimerImpl::Shutdown();
621 :
622 1419 : NS_ProcessPendingEvents(thread);
623 :
624 : // Shutdown all remaining threads. This method does not return until
625 : // all threads created using the thread manager (with the exception of
626 : // the main thread) have exited.
627 1419 : nsThreadManager::get()->Shutdown();
628 :
629 1419 : NS_ProcessPendingEvents(thread);
630 :
631 1419 : HangMonitor::NotifyActivity();
632 :
633 : // We save the "xpcom-shutdown-loaders" observers to notify after
634 : // the observerservice is gone.
635 1419 : if (observerService) {
636 1419 : observerService->
637 : EnumerateObservers(NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID,
638 1419 : getter_AddRefs(moduleLoaders));
639 :
640 1419 : observerService->Shutdown();
641 : }
642 : }
643 :
644 : // Free ClearOnShutdown()'ed smart pointers. This needs to happen *after*
645 : // we've finished notifying observers of XPCOM shutdown, because shutdown
646 : // observers themselves might call ClearOnShutdown().
647 1419 : mozilla::KillClearOnShutdown();
648 :
649 : // XPCOM is officially in shutdown mode NOW
650 : // Set this only after the observers have been notified as this
651 : // will cause servicemanager to become inaccessible.
652 1419 : mozilla::services::Shutdown();
653 :
654 : #ifdef DEBUG_dougt
655 : fprintf(stderr, "* * * * XPCOM shutdown. Access will be denied * * * * \n");
656 : #endif
657 : // We may have AddRef'd for the caller of NS_InitXPCOM, so release it
658 : // here again:
659 1419 : NS_IF_RELEASE(servMgr);
660 :
661 : // Shutdown global servicemanager
662 1419 : if (nsComponentManagerImpl::gComponentManager) {
663 1419 : nsComponentManagerImpl::gComponentManager->FreeServices();
664 : }
665 :
666 : // Release the directory service
667 1419 : NS_IF_RELEASE(nsDirectoryService::gService);
668 :
669 1419 : nsCycleCollector_shutdown();
670 :
671 1419 : if (moduleLoaders) {
672 : bool more;
673 2838 : nsCOMPtr<nsISupports> el;
674 3803 : while (NS_SUCCEEDED(moduleLoaders->HasMoreElements(&more)) &&
675 : more) {
676 965 : moduleLoaders->GetNext(getter_AddRefs(el));
677 :
678 : // Don't worry about weak-reference observers here: there is
679 : // no reason for weak-ref observers to register for
680 : // xpcom-shutdown-loaders
681 :
682 1930 : nsCOMPtr<nsIObserver> obs(do_QueryInterface(el));
683 965 : if (obs)
684 965 : (void) obs->Observe(nsnull,
685 : NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID,
686 965 : nsnull);
687 : }
688 :
689 1419 : moduleLoaders = nsnull;
690 : }
691 :
692 : // Shutdown nsLocalFile string conversion
693 1419 : NS_ShutdownLocalFile();
694 : #ifdef XP_UNIX
695 1419 : NS_ShutdownNativeCharsetUtils();
696 : #endif
697 :
698 : // Shutdown xpcom. This will release all loaders and cause others holding
699 : // a refcount to the component manager to release it.
700 1419 : if (nsComponentManagerImpl::gComponentManager) {
701 1419 : rv = (nsComponentManagerImpl::gComponentManager)->Shutdown();
702 1419 : NS_ASSERTION(NS_SUCCEEDED(rv), "Component Manager shutdown failed.");
703 : } else
704 0 : NS_WARNING("Component Manager was never created ...");
705 :
706 : // Release our own singletons
707 : // Do this _after_ shutting down the component manager, because the
708 : // JS component loader will use XPConnect to call nsIModule::canUnload,
709 : // and that will spin up the InterfaceInfoManager again -- bad mojo
710 1419 : xptiInterfaceInfoManager::FreeInterfaceInfoManager();
711 :
712 : // Finally, release the component manager last because it unloads the
713 : // libraries:
714 1419 : if (nsComponentManagerImpl::gComponentManager) {
715 : nsrefcnt cnt;
716 1419 : NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt);
717 1419 : NS_ASSERTION(cnt == 0, "Component Manager being held past XPCOM shutdown.");
718 : }
719 1419 : nsComponentManagerImpl::gComponentManager = nsnull;
720 1419 : nsCategoryManager::Destroy();
721 :
722 1419 : NS_PurgeAtomTable();
723 :
724 1419 : NS_IF_RELEASE(gDebug);
725 :
726 1419 : if (sIOThread) {
727 1419 : delete sIOThread;
728 1419 : sIOThread = nsnull;
729 : }
730 1419 : if (sMessageLoop) {
731 1419 : delete sMessageLoop;
732 1419 : sMessageLoop = nsnull;
733 : }
734 1419 : if (sCommandLineWasInitialized) {
735 1419 : CommandLine::Terminate();
736 1419 : sCommandLineWasInitialized = false;
737 : }
738 1419 : if (sExitManager) {
739 1419 : delete sExitManager;
740 1419 : sExitManager = nsnull;
741 : }
742 :
743 1419 : Omnijar::CleanUp();
744 :
745 1419 : HangMonitor::Shutdown();
746 :
747 1419 : NS_LogTerm();
748 :
749 1419 : return NS_OK;
750 : }
751 :
752 4392 : } // namespace mozilla
|