Bug 545892 - Always pass WM_NCPAINT events to the default event procedure. r=bent...
[mozilla-central.git] / xpcom / build / nsXPComInit.cpp
blob2d7f2d47f2fc6fffbd48b4d5a966680a10c019b9
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
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/
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.
16 * The Original Code is mozilla.org code.
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.
23 * Contributor(s):
24 * Benjamin Smedberg <benjamin@smedbergs.us>
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.
38 * ***** END LICENSE BLOCK ***** */
40 #ifdef MOZ_IPC
41 #include "base/basictypes.h"
42 #endif
44 #include "mozilla/XPCOM.h"
45 #include "nsXULAppAPI.h"
47 #include "nsXPCOMPrivate.h"
48 #include "nsXPCOMCIDInternal.h"
50 #include "nsStaticComponents.h"
51 #include "prlink.h"
53 #include "nsObserverList.h"
54 #include "nsObserverService.h"
55 #include "nsProperties.h"
56 #include "nsPersistentProperties.h"
57 #include "nsScriptableInputStream.h"
58 #include "nsBinaryStream.h"
59 #include "nsStorageStream.h"
60 #include "nsPipe.h"
62 #include "nsMemoryImpl.h"
63 #include "nsDebugImpl.h"
64 #include "nsTraceRefcntImpl.h"
65 #include "nsErrorService.h"
66 #include "nsByteBuffer.h"
68 #include "nsSupportsArray.h"
69 #include "nsArray.h"
70 #include "nsINIParserImpl.h"
71 #include "nsSupportsPrimitives.h"
72 #include "nsConsoleService.h"
73 #include "nsExceptionService.h"
75 #include "nsComponentManager.h"
76 #include "nsCategoryManagerUtils.h"
77 #include "nsIServiceManager.h"
79 #include "nsThreadManager.h"
80 #include "nsThreadPool.h"
82 #include "nsIProxyObjectManager.h"
83 #include "nsProxyEventPrivate.h" // access to the impl of nsProxyObjectManager for the generic factory registration.
85 #include "xptinfo.h"
86 #include "nsIInterfaceInfoManager.h"
87 #include "xptiprivate.h"
89 #include "nsTimerImpl.h"
90 #include "TimerThread.h"
92 #include "nsThread.h"
93 #include "nsProcess.h"
94 #include "nsEnvironment.h"
95 #include "nsVersionComparatorImpl.h"
97 #include "nsILocalFile.h"
98 #include "nsLocalFile.h"
99 #if defined(XP_UNIX) || defined(XP_OS2)
100 #include "nsNativeCharsetUtils.h"
101 #endif
102 #include "nsDirectoryService.h"
103 #include "nsDirectoryServiceDefs.h"
104 #include "nsCategoryManager.h"
105 #include "nsICategoryManager.h"
106 #include "nsMultiplexInputStream.h"
108 #include "nsStringStream.h"
109 extern nsresult nsStringInputStreamConstructor(nsISupports *, REFNSIID, void **);
111 #include "nsFastLoadService.h"
113 #include "nsAtomService.h"
114 #include "nsAtomTable.h"
115 #include "nsTraceRefcnt.h"
116 #include "nsTimelineService.h"
118 #include "nsHashPropertyBag.h"
120 #include "nsUnicharInputStream.h"
121 #include "nsVariant.h"
123 #include "nsUUIDGenerator.h"
125 #include "nsIOUtil.h"
127 #include "nsRecyclingAllocator.h"
129 #include "SpecialSystemDirectory.h"
131 #if defined(XP_WIN)
132 #include "nsWindowsRegKey.h"
133 #endif
135 #ifdef XP_MACOSX
136 #include "nsMacUtilsImpl.h"
137 #endif
139 #include "nsSystemInfo.h"
140 #include "nsMemoryReporterManager.h"
142 #include <locale.h>
143 #include "mozilla/Services.h"
144 #include "mozilla/FunctionTimer.h"
145 #include "mozilla/Omnijar.h"
147 #include "nsChromeRegistry.h"
148 #include "nsChromeProtocolHandler.h"
150 #ifdef MOZ_ENABLE_LIBXUL
151 #include "mozilla/scache/StartupCache.h"
152 #endif
154 #ifdef MOZ_IPC
155 #include "base/at_exit.h"
156 #include "base/command_line.h"
157 #include "base/message_loop.h"
159 #include "mozilla/ipc/BrowserProcessSubThread.h"
161 using base::AtExitManager;
162 using mozilla::ipc::BrowserProcessSubThread;
164 namespace {
166 static AtExitManager* sExitManager;
167 static MessageLoop* sMessageLoop;
168 static bool sCommandLineWasInitialized;
169 static BrowserProcessSubThread* sIOThread;
171 } /* anonymous namespace */
172 #endif
174 // Registry Factory creation function defined in nsRegistry.cpp
175 // We hook into this function locally to create and register the registry
176 // Since noone outside xpcom needs to know about this and nsRegistry.cpp
177 // does not have a local include file, we are putting this definition
178 // here rather than in nsIRegistry.h
179 extern nsresult NS_RegistryGetFactory(nsIFactory** aFactory);
180 extern nsresult NS_CategoryManagerGetFactory( nsIFactory** );
182 #ifdef DEBUG
183 extern void _FreeAutoLockStatics();
184 #endif
186 NS_GENERIC_FACTORY_CONSTRUCTOR(nsProcess)
188 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsIDImpl)
189 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsStringImpl)
190 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsCStringImpl)
191 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRBoolImpl)
192 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint8Impl)
193 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint16Impl)
194 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint32Impl)
195 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint64Impl)
196 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRTimeImpl)
197 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsCharImpl)
198 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt16Impl)
199 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt32Impl)
200 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt64Impl)
201 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsFloatImpl)
202 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsDoubleImpl)
203 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsVoidImpl)
204 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsInterfacePointerImpl)
206 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsConsoleService, Init)
207 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAtomService)
208 NS_GENERIC_FACTORY_CONSTRUCTOR(nsExceptionService)
209 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimerImpl)
210 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryOutputStream)
211 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryInputStream)
212 NS_GENERIC_FACTORY_CONSTRUCTOR(nsStorageStream)
213 NS_GENERIC_FACTORY_CONSTRUCTOR(nsVersionComparatorImpl)
215 NS_GENERIC_FACTORY_CONSTRUCTOR(nsVariant)
217 NS_GENERIC_FACTORY_CONSTRUCTOR(nsRecyclingAllocatorImpl)
219 #ifdef MOZ_TIMELINE
220 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimelineService)
221 #endif
223 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHashPropertyBag, Init)
225 NS_GENERIC_AGGREGATED_CONSTRUCTOR_INIT(nsProperties, Init)
227 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUUIDGenerator, Init)
229 #ifdef XP_MACOSX
230 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacUtilsImpl)
231 #endif
233 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemInfo, Init)
235 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsMemoryReporterManager, Init)
237 NS_GENERIC_FACTORY_CONSTRUCTOR(nsIOUtil)
239 static nsresult
240 nsThreadManagerGetSingleton(nsISupports* outer,
241 const nsIID& aIID,
242 void* *aInstancePtr)
244 NS_ASSERTION(aInstancePtr, "null outptr");
245 NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION);
247 return nsThreadManager::get()->QueryInterface(aIID, aInstancePtr);
250 NS_GENERIC_FACTORY_CONSTRUCTOR(nsThreadPool)
252 static nsresult
253 nsXPTIInterfaceInfoManagerGetSingleton(nsISupports* outer,
254 const nsIID& aIID,
255 void* *aInstancePtr)
257 NS_ASSERTION(aInstancePtr, "null outptr");
258 NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION);
260 nsCOMPtr<nsIInterfaceInfoManager> iim
261 (xptiInterfaceInfoManager::GetSingleton());
262 if (!iim)
263 return NS_ERROR_FAILURE;
265 return iim->QueryInterface(aIID, aInstancePtr);
268 nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = NULL;
269 PRBool gXPCOMShuttingDown = PR_FALSE;
271 static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
272 static NS_DEFINE_CID(kINIParserFactoryCID, NS_INIPARSERFACTORY_CID);
273 static NS_DEFINE_CID(kSimpleUnicharStreamFactoryCID, NS_SIMPLE_UNICHAR_STREAM_FACTORY_CID);
275 NS_DEFINE_NAMED_CID(NS_CHROMEREGISTRY_CID);
276 NS_DEFINE_NAMED_CID(NS_CHROMEPROTOCOLHANDLER_CID);
278 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsChromeRegistry,
279 nsChromeRegistry::GetSingleton)
280 NS_GENERIC_FACTORY_CONSTRUCTOR(nsChromeProtocolHandler)
282 #define NS_PERSISTENTPROPERTIES_CID NS_IPERSISTENTPROPERTIES_CID /* sigh */
283 #define NS_XPCOMPROXY_CID NS_PROXYEVENT_MANAGER_CID
285 static already_AddRefed<nsIFactory>
286 CreateINIParserFactory(const mozilla::Module& module,
287 const mozilla::Module::CIDEntry& entry)
289 nsIFactory* f = new nsINIParserFactory();
290 f->AddRef();
291 return f;
294 static already_AddRefed<nsIFactory>
295 CreateUnicharStreamFactory(const mozilla::Module& module,
296 const mozilla::Module::CIDEntry& entry)
298 return nsSimpleUnicharStreamFactory::GetInstance();
301 #define COMPONENT(NAME, Ctor) static NS_DEFINE_CID(kNS_##NAME##_CID, NS_##NAME##_CID);
302 #include "XPCOMModule.inc"
303 #undef COMPONENT
305 #define COMPONENT(NAME, Ctor) { &kNS_##NAME##_CID, false, NULL, Ctor },
306 const mozilla::Module::CIDEntry kXPCOMCIDEntries[] = {
307 { &kComponentManagerCID, true, NULL, nsComponentManagerImpl::Create },
308 { &kINIParserFactoryCID, false, CreateINIParserFactory },
309 { &kSimpleUnicharStreamFactoryCID, false, CreateUnicharStreamFactory },
310 #include "XPCOMModule.inc"
311 { &kNS_CHROMEREGISTRY_CID, false, NULL, nsChromeRegistryConstructor },
312 { &kNS_CHROMEPROTOCOLHANDLER_CID, false, NULL, nsChromeProtocolHandlerConstructor },
313 { NULL }
315 #undef COMPONENT
317 #define COMPONENT(NAME, Ctor) { NS_##NAME##_CONTRACTID, &kNS_##NAME##_CID },
318 const mozilla::Module::ContractIDEntry kXPCOMContracts[] = {
319 #include "XPCOMModule.inc"
320 { NS_CHROMEREGISTRY_CONTRACTID, &kNS_CHROMEREGISTRY_CID },
321 { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "chrome", &kNS_CHROMEPROTOCOLHANDLER_CID },
322 { NS_INIPARSERFACTORY_CONTRACTID, &kINIParserFactoryCID },
323 { NULL }
325 #undef COMPONENT
327 const mozilla::Module kXPCOMModule = { mozilla::Module::kVersion, kXPCOMCIDEntries, kXPCOMContracts };
329 // gDebug will be freed during shutdown.
330 static nsIDebug* gDebug = nsnull;
332 EXPORT_XPCOM_API(nsresult)
333 NS_GetDebug(nsIDebug** result)
335 return nsDebugImpl::Create(nsnull,
336 NS_GET_IID(nsIDebug),
337 (void**) result);
340 EXPORT_XPCOM_API(nsresult)
341 NS_GetTraceRefcnt(nsITraceRefcnt** result)
343 return nsTraceRefcntImpl::Create(nsnull,
344 NS_GET_IID(nsITraceRefcnt),
345 (void**) result);
348 EXPORT_XPCOM_API(nsresult)
349 NS_InitXPCOM(nsIServiceManager* *result,
350 nsIFile* binDirectory)
352 return NS_InitXPCOM2(result, binDirectory, nsnull);
355 EXPORT_XPCOM_API(nsresult)
356 NS_InitXPCOM2(nsIServiceManager* *result,
357 nsIFile* binDirectory,
358 nsIDirectoryServiceProvider* appFileLocationProvider)
360 NS_TIME_FUNCTION;
362 nsresult rv = NS_OK;
364 // We are not shutting down
365 gXPCOMShuttingDown = PR_FALSE;
367 NS_TIME_FUNCTION_MARK("Next: log init");
369 NS_LogInit();
371 #ifdef MOZ_IPC
372 NS_TIME_FUNCTION_MARK("Next: IPC init");
374 // Set up chromium libs
375 NS_ASSERTION(!sExitManager && !sMessageLoop, "Bad logic!");
377 if (!AtExitManager::AlreadyRegistered()) {
378 sExitManager = new AtExitManager();
379 NS_ENSURE_STATE(sExitManager);
382 if (!MessageLoop::current()) {
383 sMessageLoop = new MessageLoopForUI(MessageLoop::TYPE_MOZILLA_UI);
384 NS_ENSURE_STATE(sMessageLoop);
387 if (XRE_GetProcessType() == GeckoProcessType_Default &&
388 !BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)) {
389 scoped_ptr<BrowserProcessSubThread> ioThread(
390 new BrowserProcessSubThread(BrowserProcessSubThread::IO));
391 NS_ENSURE_TRUE(ioThread.get(), NS_ERROR_OUT_OF_MEMORY);
393 base::Thread::Options options;
394 options.message_loop_type = MessageLoop::TYPE_IO;
395 NS_ENSURE_TRUE(ioThread->StartWithOptions(options), NS_ERROR_FAILURE);
397 sIOThread = ioThread.release();
399 #endif
401 NS_TIME_FUNCTION_MARK("Next: thread manager init");
403 // Establish the main thread here.
404 rv = nsThreadManager::get()->Init();
405 if (NS_FAILED(rv)) return rv;
407 NS_TIME_FUNCTION_MARK("Next: timer startup");
409 // Set up the timer globals/timer thread
410 rv = nsTimerImpl::Startup();
411 NS_ENSURE_SUCCESS(rv, rv);
413 #if !defined(WINCE) && !defined(ANDROID)
414 NS_TIME_FUNCTION_MARK("Next: setlocale");
416 // If the locale hasn't already been setup by our embedder,
417 // get us out of the "C" locale and into the system
418 if (strcmp(setlocale(LC_ALL, NULL), "C") == 0)
419 setlocale(LC_ALL, "");
420 #endif
422 #if defined(XP_UNIX) || defined(XP_OS2)
423 NS_TIME_FUNCTION_MARK("Next: startup native charset utils");
425 NS_StartupNativeCharsetUtils();
426 #endif
428 NS_TIME_FUNCTION_MARK("Next: startup local file");
430 NS_StartupLocalFile();
432 StartupSpecialSystemDirectory();
434 rv = nsDirectoryService::RealInit();
435 if (NS_FAILED(rv))
436 return rv;
438 nsCOMPtr<nsIFile> xpcomLib;
440 PRBool value;
441 if (binDirectory)
443 rv = binDirectory->IsDirectory(&value);
445 if (NS_SUCCEEDED(rv) && value) {
446 nsDirectoryService::gService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, binDirectory);
447 binDirectory->Clone(getter_AddRefs(xpcomLib));
450 else {
451 nsDirectoryService::gService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
452 NS_GET_IID(nsIFile),
453 getter_AddRefs(xpcomLib));
456 if (xpcomLib) {
457 xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL));
458 nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);
461 if (appFileLocationProvider) {
462 rv = nsDirectoryService::gService->RegisterProvider(appFileLocationProvider);
463 if (NS_FAILED(rv)) return rv;
466 #ifdef MOZ_OMNIJAR
467 NS_TIME_FUNCTION_MARK("Next: Omnijar init");
469 if (!mozilla::OmnijarPath()) {
470 nsCOMPtr<nsILocalFile> omnijar;
471 nsCOMPtr<nsIFile> file;
473 rv = NS_ERROR_FAILURE;
474 nsDirectoryService::gService->Get(NS_GRE_DIR,
475 NS_GET_IID(nsIFile),
476 getter_AddRefs(file));
477 if (file)
478 rv = file->Append(NS_LITERAL_STRING("omni.jar"));
479 if (NS_SUCCEEDED(rv))
480 omnijar = do_QueryInterface(file);
481 if (NS_SUCCEEDED(rv))
482 mozilla::SetOmnijar(omnijar);
484 #endif
486 #ifdef MOZ_IPC
487 if ((sCommandLineWasInitialized = !CommandLine::IsInitialized())) {
488 NS_TIME_FUNCTION_MARK("Next: IPC command line init");
490 #ifdef OS_WIN
491 CommandLine::Init(0, nsnull);
492 #else
493 nsCOMPtr<nsIFile> binaryFile;
494 nsDirectoryService::gService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
495 NS_GET_IID(nsIFile),
496 getter_AddRefs(binaryFile));
497 NS_ENSURE_STATE(binaryFile);
499 rv = binaryFile->AppendNative(NS_LITERAL_CSTRING("nonexistent-executable"));
500 NS_ENSURE_SUCCESS(rv, rv);
502 nsCString binaryPath;
503 rv = binaryFile->GetNativePath(binaryPath);
504 NS_ENSURE_SUCCESS(rv, rv);
506 static char const *const argv = { strdup(binaryPath.get()) };
507 CommandLine::Init(1, &argv);
508 #endif
510 #endif
512 NS_ASSERTION(nsComponentManagerImpl::gComponentManager == NULL, "CompMgr not null at init");
514 NS_TIME_FUNCTION_MARK("Next: component manager init");
516 // Create the Component/Service Manager
517 nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl();
518 NS_ADDREF(nsComponentManagerImpl::gComponentManager);
520 rv = nsCycleCollector_startup();
521 if (NS_FAILED(rv)) return rv;
523 rv = nsComponentManagerImpl::gComponentManager->Init();
524 if (NS_FAILED(rv))
526 NS_RELEASE(nsComponentManagerImpl::gComponentManager);
527 return rv;
530 if (result) {
531 NS_ADDREF(*result = nsComponentManagerImpl::gComponentManager);
534 NS_TIME_FUNCTION_MARK("Next: cycle collector startup");
536 NS_TIME_FUNCTION_MARK("Next: interface info manager init");
538 // The iimanager constructor searches and registers XPT files.
539 // (We trigger the singleton's lazy construction here to make that happen.)
540 (void) xptiInterfaceInfoManager::GetSingleton();
542 NS_TIME_FUNCTION_MARK("Next: register category providers");
544 // After autoreg, but before we actually instantiate any components,
545 // add any services listed in the "xpcom-directory-providers" category
546 // to the directory service.
547 nsDirectoryService::gService->RegisterCategoryProviders();
549 #ifdef MOZ_ENABLE_LIBXUL
550 mozilla::scache::StartupCache::GetSingleton();
551 #endif
552 NS_TIME_FUNCTION_MARK("Next: create services from category");
554 // Notify observers of xpcom autoregistration start
555 NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_CATEGORY,
556 nsnull,
557 NS_XPCOM_STARTUP_OBSERVER_ID);
559 return NS_OK;
564 // NS_ShutdownXPCOM()
566 // The shutdown sequence for xpcom would be
568 // - Notify "xpcom-shutdown" for modules to release primary (root) references
569 // - Shutdown XPCOM timers
570 // - Notify "xpcom-shutdown-threads" for thread joins
571 // - Shutdown the event queues
572 // - Release the Global Service Manager
573 // - Release all service instances held by the global service manager
574 // - Release the Global Service Manager itself
575 // - Release the Component Manager
576 // - Release all factories cached by the Component Manager
577 // - Notify module loaders to shut down
578 // - Unload Libraries
579 // - Release Contractid Cache held by Component Manager
580 // - Release dll abstraction held by Component Manager
581 // - Release the Registry held by Component Manager
582 // - Finally, release the component manager itself
584 EXPORT_XPCOM_API(nsresult)
585 NS_ShutdownXPCOM(nsIServiceManager* servMgr)
587 return mozilla::ShutdownXPCOM(servMgr);
590 namespace mozilla {
592 nsresult
593 ShutdownXPCOM(nsIServiceManager* servMgr)
595 NS_ENSURE_STATE(NS_IsMainThread());
597 nsresult rv;
598 nsCOMPtr<nsISimpleEnumerator> moduleLoaders;
600 // Notify observers of xpcom shutting down
602 // Block it so that the COMPtr will get deleted before we hit
603 // servicemanager shutdown
605 nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
606 NS_ENSURE_STATE(thread);
608 nsRefPtr<nsObserverService> observerService;
609 CallGetService("@mozilla.org/observer-service;1",
610 (nsObserverService**) getter_AddRefs(observerService));
612 if (observerService)
614 (void) observerService->
615 NotifyObservers(nsnull, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID,
616 nsnull);
618 nsCOMPtr<nsIServiceManager> mgr;
619 rv = NS_GetServiceManager(getter_AddRefs(mgr));
620 if (NS_SUCCEEDED(rv))
622 (void) observerService->
623 NotifyObservers(mgr, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
624 nsnull);
628 NS_ProcessPendingEvents(thread);
629 #ifdef MOZ_ENABLE_LIBXUL
630 mozilla::scache::StartupCache::DeleteSingleton();
631 #endif
632 if (observerService)
633 (void) observerService->
634 NotifyObservers(nsnull, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID,
635 nsnull);
637 NS_ProcessPendingEvents(thread);
639 // Shutdown the timer thread and all timers that might still be alive before
640 // shutting down the component manager
641 nsTimerImpl::Shutdown();
643 NS_ProcessPendingEvents(thread);
645 // Shutdown all remaining threads. This method does not return until
646 // all threads created using the thread manager (with the exception of
647 // the main thread) have exited.
648 nsThreadManager::get()->Shutdown();
650 NS_ProcessPendingEvents(thread);
652 // We save the "xpcom-shutdown-loaders" observers to notify after
653 // the observerservice is gone.
654 if (observerService) {
655 observerService->
656 EnumerateObservers(NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID,
657 getter_AddRefs(moduleLoaders));
659 observerService->Shutdown();
663 // XPCOM is officially in shutdown mode NOW
664 // Set this only after the observers have been notified as this
665 // will cause servicemanager to become inaccessible.
666 mozilla::services::Shutdown();
668 #ifdef DEBUG_dougt
669 fprintf(stderr, "* * * * XPCOM shutdown. Access will be denied * * * * \n");
670 #endif
671 // We may have AddRef'd for the caller of NS_InitXPCOM, so release it
672 // here again:
673 NS_IF_RELEASE(servMgr);
675 // Shutdown global servicemanager
676 if (nsComponentManagerImpl::gComponentManager) {
677 nsComponentManagerImpl::gComponentManager->FreeServices();
680 nsProxyObjectManager::Shutdown();
682 // Release the directory service
683 NS_IF_RELEASE(nsDirectoryService::gService);
685 nsCycleCollector_shutdown();
687 if (moduleLoaders) {
688 PRBool more;
689 nsCOMPtr<nsISupports> el;
690 while (NS_SUCCEEDED(moduleLoaders->HasMoreElements(&more)) &&
691 more) {
692 moduleLoaders->GetNext(getter_AddRefs(el));
694 // Don't worry about weak-reference observers here: there is
695 // no reason for weak-ref observers to register for
696 // xpcom-shutdown-loaders
698 nsCOMPtr<nsIObserver> obs(do_QueryInterface(el));
699 if (obs)
700 (void) obs->Observe(nsnull,
701 NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID,
702 nsnull);
705 moduleLoaders = nsnull;
708 // Shutdown nsLocalFile string conversion
709 NS_ShutdownLocalFile();
710 #ifdef XP_UNIX
711 NS_ShutdownNativeCharsetUtils();
712 #endif
714 // Shutdown xpcom. This will release all loaders and cause others holding
715 // a refcount to the component manager to release it.
716 if (nsComponentManagerImpl::gComponentManager) {
717 rv = (nsComponentManagerImpl::gComponentManager)->Shutdown();
718 NS_ASSERTION(NS_SUCCEEDED(rv), "Component Manager shutdown failed.");
719 } else
720 NS_WARNING("Component Manager was never created ...");
722 // Release our own singletons
723 // Do this _after_ shutting down the component manager, because the
724 // JS component loader will use XPConnect to call nsIModule::canUnload,
725 // and that will spin up the InterfaceInfoManager again -- bad mojo
726 xptiInterfaceInfoManager::FreeInterfaceInfoManager();
728 // Finally, release the component manager last because it unloads the
729 // libraries:
730 if (nsComponentManagerImpl::gComponentManager) {
731 nsrefcnt cnt;
732 NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt);
733 NS_ASSERTION(cnt == 0, "Component Manager being held past XPCOM shutdown.");
735 nsComponentManagerImpl::gComponentManager = nsnull;
736 nsCategoryManager::Destroy();
738 #ifdef DEBUG
739 // FIXME BUG 456272: this should disappear
740 _FreeAutoLockStatics();
741 #endif
743 ShutdownSpecialSystemDirectory();
745 NS_PurgeAtomTable();
747 NS_IF_RELEASE(gDebug);
749 #ifdef MOZ_IPC
750 if (sIOThread) {
751 delete sIOThread;
752 sIOThread = nsnull;
754 if (sMessageLoop) {
755 delete sMessageLoop;
756 sMessageLoop = nsnull;
758 if (sCommandLineWasInitialized) {
759 CommandLine::Terminate();
760 sCommandLineWasInitialized = false;
762 if (sExitManager) {
763 delete sExitManager;
764 sExitManager = nsnull;
766 #endif
768 #ifdef MOZ_OMNIJAR
769 mozilla::SetOmnijar(nsnull);
770 #endif
772 NS_LogTerm();
774 return NS_OK;
777 } // namespace mozilla