Bug 487345 - Crash [@ nsObjectLoadingContent::Instantiate] when enabling Flashblock...
[mozilla-1.9.git] / xpcom / build / nsXPComInit.cpp
blob6aa2fdebf98e56d25270090527a10469827c09b0
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 #include "nsXPCOM.h"
41 #include "nsXPCOMPrivate.h"
42 #include "nsXPCOMCIDInternal.h"
43 #include "nscore.h"
44 #include "nsIClassInfoImpl.h"
45 #include "nsStaticComponents.h"
46 #include "prlink.h"
47 #include "nsCOMPtr.h"
48 #include "nsObserverList.h"
49 #include "nsObserverService.h"
50 #include "nsProperties.h"
51 #include "nsIProperties.h"
52 #include "nsPersistentProperties.h"
53 #include "nsScriptableInputStream.h"
54 #include "nsBinaryStream.h"
55 #include "nsStorageStream.h"
56 #include "nsPipe.h"
58 #include "nsMemoryImpl.h"
59 #include "nsDebugImpl.h"
60 #include "nsTraceRefcntImpl.h"
61 #include "nsErrorService.h"
62 #include "nsByteBuffer.h"
64 #include "nsSupportsArray.h"
65 #include "nsArray.h"
66 #include "nsINIParserImpl.h"
67 #include "nsSupportsPrimitives.h"
68 #include "nsConsoleService.h"
69 #include "nsExceptionService.h"
71 #include "nsComponentManager.h"
72 #include "nsCategoryManagerUtils.h"
73 #include "nsIServiceManager.h"
74 #include "nsGenericFactory.h"
76 #include "nsThreadManager.h"
77 #include "nsThreadPool.h"
79 #include "nsIProxyObjectManager.h"
80 #include "nsProxyEventPrivate.h" // access to the impl of nsProxyObjectManager for the generic factory registration.
82 #include "xptinfo.h"
83 #include "nsIInterfaceInfoManager.h"
84 #include "xptiprivate.h"
86 #include "nsTimerImpl.h"
87 #include "TimerThread.h"
89 #include "nsThread.h"
90 #include "nsProcess.h"
91 #include "nsEnvironment.h"
92 #include "nsVersionComparatorImpl.h"
94 #include "nsILocalFile.h"
95 #include "nsLocalFile.h"
96 #if defined(XP_UNIX) || defined(XP_OS2)
97 #include "nsNativeCharsetUtils.h"
98 #endif
99 #include "nsDirectoryService.h"
100 #include "nsDirectoryServiceDefs.h"
101 #include "nsCategoryManager.h"
102 #include "nsICategoryManager.h"
103 #include "nsMultiplexInputStream.h"
105 #include "nsStringStream.h"
106 extern NS_METHOD nsStringInputStreamConstructor(nsISupports *, REFNSIID, void **);
107 NS_DECL_CLASSINFO(nsStringInputStream)
109 #include "nsFastLoadService.h"
111 #include "nsAtomService.h"
112 #include "nsAtomTable.h"
113 #include "nsTraceRefcnt.h"
114 #include "nsTimelineService.h"
116 #include "nsHashPropertyBag.h"
118 #include "nsUnicharInputStream.h"
119 #include "nsVariant.h"
121 #include "nsUUIDGenerator.h"
123 #ifdef GC_LEAK_DETECTOR
124 #include "nsLeakDetector.h"
125 #endif
126 #include "nsRecyclingAllocator.h"
128 #include "SpecialSystemDirectory.h"
130 #if defined(XP_WIN) && !defined(WINCE)
131 #include "nsWindowsRegKey.h"
132 #endif
134 #ifdef XP_MACOSX
135 #include "nsMacUtilsImpl.h"
136 #endif
138 #include "nsSystemInfo.h"
139 #include "nsMemoryReporterManager.h"
141 #include <locale.h>
143 // Registry Factory creation function defined in nsRegistry.cpp
144 // We hook into this function locally to create and register the registry
145 // Since noone outside xpcom needs to know about this and nsRegistry.cpp
146 // does not have a local include file, we are putting this definition
147 // here rather than in nsIRegistry.h
148 extern nsresult NS_RegistryGetFactory(nsIFactory** aFactory);
149 extern nsresult NS_CategoryManagerGetFactory( nsIFactory** );
151 #ifdef DEBUG
152 extern void _FreeAutoLockStatics();
153 #endif
155 static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
156 static NS_DEFINE_CID(kMemoryCID, NS_MEMORY_CID);
157 static NS_DEFINE_CID(kINIParserFactoryCID, NS_INIPARSERFACTORY_CID);
158 static NS_DEFINE_CID(kSimpleUnicharStreamFactoryCID, NS_SIMPLE_UNICHAR_STREAM_FACTORY_CID);
160 NS_GENERIC_FACTORY_CONSTRUCTOR(nsProcess)
162 #define NS_ENVIRONMENT_CLASSNAME "Environment Service"
164 #include "nsXPCOM.h"
165 // ds/nsISupportsPrimitives
166 #define NS_SUPPORTS_ID_CLASSNAME "Supports ID"
167 #define NS_SUPPORTS_CSTRING_CLASSNAME "Supports String"
168 #define NS_SUPPORTS_STRING_CLASSNAME "Supports WString"
169 #define NS_SUPPORTS_PRBOOL_CLASSNAME "Supports PRBool"
170 #define NS_SUPPORTS_PRUINT8_CLASSNAME "Supports PRUint8"
171 #define NS_SUPPORTS_PRUINT16_CLASSNAME "Supports PRUint16"
172 #define NS_SUPPORTS_PRUINT32_CLASSNAME "Supports PRUint32"
173 #define NS_SUPPORTS_PRUINT64_CLASSNAME "Supports PRUint64"
174 #define NS_SUPPORTS_PRTIME_CLASSNAME "Supports PRTime"
175 #define NS_SUPPORTS_CHAR_CLASSNAME "Supports Char"
176 #define NS_SUPPORTS_PRINT16_CLASSNAME "Supports PRInt16"
177 #define NS_SUPPORTS_PRINT32_CLASSNAME "Supports PRInt32"
178 #define NS_SUPPORTS_PRINT64_CLASSNAME "Supports PRInt64"
179 #define NS_SUPPORTS_FLOAT_CLASSNAME "Supports float"
180 #define NS_SUPPORTS_DOUBLE_CLASSNAME "Supports double"
181 #define NS_SUPPORTS_VOID_CLASSNAME "Supports void"
182 #define NS_SUPPORTS_INTERFACE_POINTER_CLASSNAME "Supports interface pointer"
184 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsIDImpl)
185 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsStringImpl)
186 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsCStringImpl)
187 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRBoolImpl)
188 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint8Impl)
189 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint16Impl)
190 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint32Impl)
191 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint64Impl)
192 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRTimeImpl)
193 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsCharImpl)
194 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt16Impl)
195 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt32Impl)
196 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt64Impl)
197 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsFloatImpl)
198 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsDoubleImpl)
199 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsVoidImpl)
200 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsInterfacePointerImpl)
202 NS_GENERIC_FACTORY_CONSTRUCTOR(nsArray)
203 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsConsoleService, Init)
204 NS_DECL_CLASSINFO(nsConsoleService)
205 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAtomService)
206 NS_GENERIC_FACTORY_CONSTRUCTOR(nsExceptionService)
207 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimerImpl)
208 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryOutputStream)
209 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryInputStream)
210 NS_GENERIC_FACTORY_CONSTRUCTOR(nsStorageStream)
211 NS_GENERIC_FACTORY_CONSTRUCTOR(nsVersionComparatorImpl)
213 NS_GENERIC_FACTORY_CONSTRUCTOR(nsVariant)
215 NS_GENERIC_FACTORY_CONSTRUCTOR(nsRecyclingAllocatorImpl)
217 #ifdef MOZ_TIMELINE
218 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimelineService)
219 #endif
221 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHashPropertyBag, Init)
223 NS_GENERIC_AGGREGATED_CONSTRUCTOR_INIT(nsProperties, Init)
225 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUUIDGenerator, Init)
227 #ifdef XP_MACOSX
228 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacUtilsImpl)
229 #endif
231 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemInfo, Init)
233 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMemoryReporterManager)
235 static NS_METHOD
236 nsThreadManagerGetSingleton(nsISupports* outer,
237 const nsIID& aIID,
238 void* *aInstancePtr)
240 NS_ASSERTION(aInstancePtr, "null outptr");
241 NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION);
243 return nsThreadManager::get()->QueryInterface(aIID, aInstancePtr);
245 NS_DECL_CLASSINFO(nsThreadManager)
247 NS_GENERIC_FACTORY_CONSTRUCTOR(nsThreadPool)
248 NS_DECL_CLASSINFO(nsThreadPool)
250 static NS_METHOD
251 nsXPTIInterfaceInfoManagerGetSingleton(nsISupports* outer,
252 const nsIID& aIID,
253 void* *aInstancePtr)
255 NS_ASSERTION(aInstancePtr, "null outptr");
256 NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION);
258 nsCOMPtr<nsIInterfaceInfoManager> iim
259 (xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef());
260 if (!iim)
261 return NS_ERROR_FAILURE;
263 return iim->QueryInterface(aIID, aInstancePtr);
267 PR_STATIC_CALLBACK(nsresult)
268 RegisterGenericFactory(nsIComponentRegistrar* registrar,
269 const nsModuleComponentInfo *info)
271 nsresult rv;
272 nsIGenericFactory* fact;
273 rv = NS_NewGenericFactory(&fact, info);
274 if (NS_FAILED(rv)) return rv;
276 rv = registrar->RegisterFactory(info->mCID,
277 info->mDescription,
278 info->mContractID,
279 fact);
280 NS_RELEASE(fact);
281 return rv;
284 // In order to support the installer, we need
285 // to be told out of band if we should cause
286 // an autoregister. If the file ".autoreg" exists in the binary
287 // directory, we check its timestamp against the timestamp of the
288 // compreg.dat file. If the .autoreg file is newer, we autoregister.
289 static PRBool CheckUpdateFile()
291 nsresult rv;
292 nsCOMPtr<nsIFile> file;
293 rv = nsDirectoryService::gService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
294 NS_GET_IID(nsIFile),
295 getter_AddRefs(file));
297 if (NS_FAILED(rv)) {
298 NS_WARNING("Getting NS_XPCOM_CURRENT_PROCESS_DIR failed");
299 return PR_FALSE;
302 file->AppendNative(nsDependentCString(".autoreg"));
304 PRBool exists;
305 file->Exists(&exists);
306 if (!exists)
307 return PR_FALSE;
309 nsCOMPtr<nsIFile> compregFile;
310 rv = nsDirectoryService::gService->Get(NS_XPCOM_COMPONENT_REGISTRY_FILE,
311 NS_GET_IID(nsIFile),
312 getter_AddRefs(compregFile));
315 if (NS_FAILED(rv)) {
316 NS_WARNING("Getting NS_XPCOM_COMPONENT_REGISTRY_FILE failed");
317 return PR_FALSE;
320 if (NS_FAILED(compregFile->Exists(&exists)) || !exists)
321 return PR_TRUE;
323 PRInt64 compregModTime, autoregModTime;
324 compregFile->GetLastModifiedTime(&compregModTime);
325 file->GetLastModifiedTime(&autoregModTime);
327 return LL_CMP(autoregModTime, >, compregModTime);
331 nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = NULL;
332 PRBool gXPCOMShuttingDown = PR_FALSE;
334 // For each class that wishes to support nsIClassInfo, add a line like this
335 // NS_DECL_CLASSINFO(nsMyClass)
337 #define COMPONENT(NAME, Ctor) \
338 { NS_##NAME##_CLASSNAME, NS_##NAME##_CID, NS_##NAME##_CONTRACTID, Ctor }
340 #define COMPONENT_CI(NAME, Ctor, Class) \
341 { NS_##NAME##_CLASSNAME, NS_##NAME##_CID, NS_##NAME##_CONTRACTID, Ctor, \
342 NULL, NULL, NULL, NS_CI_INTERFACE_GETTER_NAME(Class), NULL, \
343 &NS_CLASSINFO_NAME(Class) }
345 #define COMPONENT_CI_FLAGS(NAME, Ctor, Class, Flags) \
346 { NS_##NAME##_CLASSNAME, NS_##NAME##_CID, NS_##NAME##_CONTRACTID, Ctor, \
347 NULL, NULL, NULL, NS_CI_INTERFACE_GETTER_NAME(Class), NULL, \
348 &NS_CLASSINFO_NAME(Class), Flags }
350 static const nsModuleComponentInfo components[] = {
351 COMPONENT(MEMORY, nsMemoryImpl::Create),
352 COMPONENT(DEBUG, nsDebugImpl::Create),
353 #define NS_ERRORSERVICE_CLASSNAME NS_ERRORSERVICE_NAME
354 COMPONENT(ERRORSERVICE, nsErrorService::Create),
356 COMPONENT(BYTEBUFFER, ByteBufferImpl::Create),
357 COMPONENT(SCRIPTABLEINPUTSTREAM, nsScriptableInputStream::Create),
358 COMPONENT(BINARYINPUTSTREAM, nsBinaryInputStreamConstructor),
359 COMPONENT(BINARYOUTPUTSTREAM, nsBinaryOutputStreamConstructor),
360 COMPONENT(STORAGESTREAM, nsStorageStreamConstructor),
361 COMPONENT(VERSIONCOMPARATOR, nsVersionComparatorImplConstructor),
362 COMPONENT(PIPE, nsPipeConstructor),
364 #define NS_PROPERTIES_CLASSNAME "Properties"
365 COMPONENT(PROPERTIES, nsPropertiesConstructor),
367 #define NS_PERSISTENTPROPERTIES_CID NS_IPERSISTENTPROPERTIES_CID /* sigh */
368 COMPONENT(PERSISTENTPROPERTIES, nsPersistentProperties::Create),
370 COMPONENT(SUPPORTSARRAY, nsSupportsArray::Create),
371 COMPONENT(ARRAY, nsArrayConstructor),
372 COMPONENT_CI_FLAGS(CONSOLESERVICE, nsConsoleServiceConstructor,
373 nsConsoleService,
374 nsIClassInfo::THREADSAFE | nsIClassInfo::SINGLETON),
375 COMPONENT(EXCEPTIONSERVICE, nsExceptionServiceConstructor),
376 COMPONENT(ATOMSERVICE, nsAtomServiceConstructor),
377 #ifdef MOZ_TIMELINE
378 COMPONENT(TIMELINESERVICE, nsTimelineServiceConstructor),
379 #endif
380 COMPONENT(OBSERVERSERVICE, nsObserverService::Create),
381 COMPONENT(GENERICFACTORY, nsGenericFactory::Create),
383 #define NS_XPCOMPROXY_CID NS_PROXYEVENT_MANAGER_CID
384 COMPONENT(XPCOMPROXY, nsProxyObjectManager::Create),
386 COMPONENT(TIMER, nsTimerImplConstructor),
388 #define COMPONENT_SUPPORTS(TYPE, Type) \
389 COMPONENT(SUPPORTS_##TYPE, nsSupports##Type##ImplConstructor)
391 COMPONENT_SUPPORTS(ID, ID),
392 COMPONENT_SUPPORTS(STRING, String),
393 COMPONENT_SUPPORTS(CSTRING, CString),
394 COMPONENT_SUPPORTS(PRBOOL, PRBool),
395 COMPONENT_SUPPORTS(PRUINT8, PRUint8),
396 COMPONENT_SUPPORTS(PRUINT16, PRUint16),
397 COMPONENT_SUPPORTS(PRUINT32, PRUint32),
398 COMPONENT_SUPPORTS(PRUINT64, PRUint64),
399 COMPONENT_SUPPORTS(PRTIME, PRTime),
400 COMPONENT_SUPPORTS(CHAR, Char),
401 COMPONENT_SUPPORTS(PRINT16, PRInt16),
402 COMPONENT_SUPPORTS(PRINT32, PRInt32),
403 COMPONENT_SUPPORTS(PRINT64, PRInt64),
404 COMPONENT_SUPPORTS(FLOAT, Float),
405 COMPONENT_SUPPORTS(DOUBLE, Double),
406 COMPONENT_SUPPORTS(VOID, Void),
407 COMPONENT_SUPPORTS(INTERFACE_POINTER, InterfacePointer),
409 #undef COMPONENT_SUPPORTS
410 #define NS_LOCAL_FILE_CLASSNAME "Local File Specification"
411 COMPONENT(LOCAL_FILE, nsLocalFile::nsLocalFileConstructor),
412 #define NS_DIRECTORY_SERVICE_CLASSNAME "nsIFile Directory Service"
413 COMPONENT(DIRECTORY_SERVICE, nsDirectoryService::Create),
414 COMPONENT(PROCESS, nsProcessConstructor),
415 COMPONENT(ENVIRONMENT, nsEnvironment::Create),
417 COMPONENT_CI_FLAGS(THREADMANAGER, nsThreadManagerGetSingleton,
418 nsThreadManager,
419 nsIClassInfo::THREADSAFE | nsIClassInfo::SINGLETON),
420 COMPONENT_CI_FLAGS(THREADPOOL, nsThreadPoolConstructor,
421 nsThreadPool, nsIClassInfo::THREADSAFE),
423 COMPONENT_CI_FLAGS(STRINGINPUTSTREAM, nsStringInputStreamConstructor,
424 nsStringInputStream, nsIClassInfo::THREADSAFE),
425 COMPONENT(MULTIPLEXINPUTSTREAM, nsMultiplexInputStreamConstructor),
427 #ifndef MOZ_NO_FAST_LOAD
428 COMPONENT(FASTLOADSERVICE, nsFastLoadService::Create),
429 #endif
431 COMPONENT(VARIANT, nsVariantConstructor),
432 COMPONENT(INTERFACEINFOMANAGER_SERVICE, nsXPTIInterfaceInfoManagerGetSingleton),
434 COMPONENT(RECYCLINGALLOCATOR, nsRecyclingAllocatorImplConstructor),
436 #define NS_HASH_PROPERTY_BAG_CLASSNAME "Hashtable Property Bag"
437 COMPONENT(HASH_PROPERTY_BAG, nsHashPropertyBagConstructor),
439 COMPONENT(UUID_GENERATOR, nsUUIDGeneratorConstructor),
441 #if defined(XP_WIN) && !defined(WINCE)
442 COMPONENT(WINDOWSREGKEY, nsWindowsRegKeyConstructor),
443 #endif
445 #ifdef XP_MACOSX
446 COMPONENT(MACUTILSIMPL, nsMacUtilsImplConstructor),
447 #endif
449 COMPONENT(SYSTEMINFO, nsSystemInfoConstructor),
450 #define NS_MEMORY_REPORTER_MANAGER_CLASSNAME "Memory Reporter Manager"
451 COMPONENT(MEMORY_REPORTER_MANAGER, nsMemoryReporterManagerConstructor),
454 #undef COMPONENT
456 const int components_length = sizeof(components) / sizeof(components[0]);
458 // gDebug will be freed during shutdown.
459 static nsIDebug* gDebug = nsnull;
461 EXPORT_XPCOM_API(nsresult)
462 NS_GetDebug(nsIDebug** result)
464 return nsDebugImpl::Create(nsnull,
465 NS_GET_IID(nsIDebug),
466 (void**) result);
469 EXPORT_XPCOM_API(nsresult)
470 NS_GetTraceRefcnt(nsITraceRefcnt** result)
472 return nsTraceRefcntImpl::Create(nsnull,
473 NS_GET_IID(nsITraceRefcnt),
474 (void**) result);
477 EXPORT_XPCOM_API(nsresult)
478 NS_InitXPCOM(nsIServiceManager* *result,
479 nsIFile* binDirectory)
481 return NS_InitXPCOM3(result, binDirectory, nsnull, nsnull, 0);
484 EXPORT_XPCOM_API(nsresult)
485 NS_InitXPCOM2(nsIServiceManager* *result,
486 nsIFile* binDirectory,
487 nsIDirectoryServiceProvider* appFileLocationProvider)
489 return NS_InitXPCOM3(result, binDirectory, appFileLocationProvider, nsnull, 0);
492 EXPORT_XPCOM_API(nsresult)
493 NS_InitXPCOM3(nsIServiceManager* *result,
494 nsIFile* binDirectory,
495 nsIDirectoryServiceProvider* appFileLocationProvider,
496 nsStaticModuleInfo const *staticComponents,
497 PRUint32 componentCount)
499 nsresult rv = NS_OK;
501 #ifdef MOZ_ENABLE_LIBXUL
502 if (!staticComponents) {
503 staticComponents = kPStaticModules;
504 componentCount = kStaticModuleCount;
506 #endif
508 // We are not shutting down
509 gXPCOMShuttingDown = PR_FALSE;
511 NS_LogInit();
513 // Establish the main thread here.
514 rv = nsThreadManager::get()->Init();
515 if (NS_FAILED(rv)) return rv;
517 // Set up the timer globals/timer thread
518 rv = nsTimerImpl::Startup();
519 NS_ENSURE_SUCCESS(rv, rv);
521 #ifndef WINCE
522 // If the locale hasn't already been setup by our embedder,
523 // get us out of the "C" locale and into the system
524 if (strcmp(setlocale(LC_ALL, NULL), "C") == 0)
525 setlocale(LC_ALL, "");
526 #endif
528 #if defined(XP_UNIX) || defined(XP_OS2)
529 NS_StartupNativeCharsetUtils();
530 #endif
531 NS_StartupLocalFile();
533 StartupSpecialSystemDirectory();
535 rv = nsDirectoryService::RealInit();
536 if (NS_FAILED(rv))
537 return rv;
539 nsCOMPtr<nsIFile> xpcomLib;
541 PRBool value;
542 if (binDirectory)
544 rv = binDirectory->IsDirectory(&value);
546 if (NS_SUCCEEDED(rv) && value) {
547 nsDirectoryService::gService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, binDirectory);
548 binDirectory->Clone(getter_AddRefs(xpcomLib));
551 else {
552 nsDirectoryService::gService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
553 NS_GET_IID(nsIFile),
554 getter_AddRefs(xpcomLib));
557 if (xpcomLib) {
558 xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL));
559 nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);
562 if (appFileLocationProvider) {
563 rv = nsDirectoryService::gService->RegisterProvider(appFileLocationProvider);
564 if (NS_FAILED(rv)) return rv;
567 NS_ASSERTION(nsComponentManagerImpl::gComponentManager == NULL, "CompMgr not null at init");
569 // Create the Component/Service Manager
570 nsComponentManagerImpl *compMgr = new nsComponentManagerImpl();
571 if (compMgr == NULL)
572 return NS_ERROR_OUT_OF_MEMORY;
573 NS_ADDREF(compMgr);
575 rv = compMgr->Init(staticComponents, componentCount);
576 if (NS_FAILED(rv))
578 NS_RELEASE(compMgr);
579 return rv;
582 nsComponentManagerImpl::gComponentManager = compMgr;
584 if (result) {
585 nsIServiceManager *serviceManager =
586 static_cast<nsIServiceManager*>(compMgr);
588 NS_ADDREF(*result = serviceManager);
591 nsCOMPtr<nsIMemory> memory;
592 NS_GetMemoryManager(getter_AddRefs(memory));
593 rv = compMgr->RegisterService(kMemoryCID, memory);
594 if (NS_FAILED(rv)) return rv;
596 rv = compMgr->RegisterService(kComponentManagerCID, static_cast<nsIComponentManager*>(compMgr));
597 if (NS_FAILED(rv)) return rv;
599 #ifdef GC_LEAK_DETECTOR
600 rv = NS_InitLeakDetector();
601 if (NS_FAILED(rv)) return rv;
602 #endif
604 rv = nsCycleCollector_startup();
605 if (NS_FAILED(rv)) return rv;
607 // 2. Register the global services with the component manager so that
608 // clients can create new objects.
610 // Category Manager
612 nsCOMPtr<nsIFactory> categoryManagerFactory;
613 if ( NS_FAILED(rv = NS_CategoryManagerGetFactory(getter_AddRefs(categoryManagerFactory))) )
614 return rv;
616 NS_DEFINE_CID(kCategoryManagerCID, NS_CATEGORYMANAGER_CID);
618 rv = compMgr->RegisterFactory(kCategoryManagerCID,
619 NS_CATEGORYMANAGER_CLASSNAME,
620 NS_CATEGORYMANAGER_CONTRACTID,
621 categoryManagerFactory,
622 PR_TRUE);
623 if ( NS_FAILED(rv) ) return rv;
626 nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(
627 static_cast<nsIComponentManager*>(compMgr), &rv);
628 if (registrar) {
629 for (int i = 0; i < components_length; i++)
630 RegisterGenericFactory(registrar, &components[i]);
632 nsCOMPtr<nsIFactory> iniParserFactory(new nsINIParserFactory());
633 if (iniParserFactory)
634 registrar->RegisterFactory(kINIParserFactoryCID,
635 "nsINIParserFactory",
636 NS_INIPARSERFACTORY_CONTRACTID,
637 iniParserFactory);
639 registrar->
640 RegisterFactory(kSimpleUnicharStreamFactoryCID,
641 "nsSimpleUnicharStreamFactory",
642 NS_SIMPLE_UNICHAR_STREAM_FACTORY_CONTRACTID,
643 nsSimpleUnicharStreamFactory::GetInstance());
646 // Pay the cost at startup time of starting this singleton.
647 nsIInterfaceInfoManager* iim =
648 xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef();
650 if (CheckUpdateFile() || NS_FAILED(
651 nsComponentManagerImpl::gComponentManager->ReadPersistentRegistry())) {
652 // If the component registry is out of date, malformed, or incomplete,
653 // autoregister the default component directories.
654 (void) iim->AutoRegisterInterfaces();
655 nsComponentManagerImpl::gComponentManager->AutoRegister(nsnull);
658 // After autoreg, but before we actually instantiate any components,
659 // add any services listed in the "xpcom-directory-providers" category
660 // to the directory service.
661 nsDirectoryService::gService->RegisterCategoryProviders();
663 // Initialize memory flusher
664 nsMemoryImpl::InitFlusher();
666 // Notify observers of xpcom autoregistration start
667 NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_CATEGORY,
668 nsnull,
669 NS_XPCOM_STARTUP_OBSERVER_ID);
671 return NS_OK;
676 // NS_ShutdownXPCOM()
678 // The shutdown sequence for xpcom would be
680 // - Notify "xpcom-shutdown" for modules to release primary (root) references
681 // - Shutdown XPCOM timers
682 // - Notify "xpcom-shutdown-threads" for thread joins
683 // - Shutdown the event queues
684 // - Release the Global Service Manager
685 // - Release all service instances held by the global service manager
686 // - Release the Global Service Manager itself
687 // - Release the Component Manager
688 // - Release all factories cached by the Component Manager
689 // - Notify module loaders to shut down
690 // - Unload Libraries
691 // - Release Contractid Cache held by Component Manager
692 // - Release dll abstraction held by Component Manager
693 // - Release the Registry held by Component Manager
694 // - Finally, release the component manager itself
696 EXPORT_XPCOM_API(nsresult)
697 NS_ShutdownXPCOM(nsIServiceManager* servMgr)
699 NS_ENSURE_STATE(NS_IsMainThread());
701 nsresult rv;
702 nsCOMPtr<nsISimpleEnumerator> moduleLoaders;
704 // Notify observers of xpcom shutting down
706 // Block it so that the COMPtr will get deleted before we hit
707 // servicemanager shutdown
709 nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
710 NS_ENSURE_STATE(thread);
712 nsRefPtr<nsObserverService> observerService;
713 CallGetService("@mozilla.org/observer-service;1",
714 (nsObserverService**) getter_AddRefs(observerService));
716 if (observerService)
718 nsCOMPtr<nsIServiceManager> mgr;
719 rv = NS_GetServiceManager(getter_AddRefs(mgr));
720 if (NS_SUCCEEDED(rv))
722 (void) observerService->
723 NotifyObservers(mgr, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
724 nsnull);
728 NS_ProcessPendingEvents(thread);
730 if (observerService)
731 (void) observerService->
732 NotifyObservers(nsnull, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID,
733 nsnull);
735 NS_ProcessPendingEvents(thread);
737 // Shutdown the timer thread and all timers that might still be alive before
738 // shutting down the component manager
739 nsTimerImpl::Shutdown();
741 NS_ProcessPendingEvents(thread);
743 // Shutdown all remaining threads. This method does not return until
744 // all threads created using the thread manager (with the exception of
745 // the main thread) have exited.
746 nsThreadManager::get()->Shutdown();
748 NS_ProcessPendingEvents(thread);
750 // We save the "xpcom-shutdown-loaders" observers to notify after
751 // the observerservice is gone.
752 if (observerService) {
753 observerService->
754 EnumerateObservers(NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID,
755 getter_AddRefs(moduleLoaders));
757 observerService->Shutdown();
761 // XPCOM is officially in shutdown mode NOW
762 // Set this only after the observers have been notified as this
763 // will cause servicemanager to become inaccessible.
764 gXPCOMShuttingDown = PR_TRUE;
766 #ifdef DEBUG_dougt
767 fprintf(stderr, "* * * * XPCOM shutdown. Access will be denied * * * * \n");
768 #endif
769 // We may have AddRef'd for the caller of NS_InitXPCOM, so release it
770 // here again:
771 NS_IF_RELEASE(servMgr);
773 // Shutdown global servicemanager
774 if (nsComponentManagerImpl::gComponentManager) {
775 nsComponentManagerImpl::gComponentManager->FreeServices();
778 nsProxyObjectManager::Shutdown();
780 // Release the directory service
781 NS_IF_RELEASE(nsDirectoryService::gService);
783 nsCycleCollector_shutdown();
785 if (moduleLoaders) {
786 PRBool more;
787 nsCOMPtr<nsISupports> el;
788 while (NS_SUCCEEDED(moduleLoaders->HasMoreElements(&more)) &&
789 more) {
790 moduleLoaders->GetNext(getter_AddRefs(el));
792 // Don't worry about weak-reference observers here: there is
793 // no reason for weak-ref observers to register for
794 // xpcom-shutdown-loaders
796 nsCOMPtr<nsIObserver> obs(do_QueryInterface(el));
797 if (obs)
798 (void) obs->Observe(nsnull,
799 NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID,
800 nsnull);
803 moduleLoaders = nsnull;
806 // Shutdown nsLocalFile string conversion
807 NS_ShutdownLocalFile();
808 #ifdef XP_UNIX
809 NS_ShutdownNativeCharsetUtils();
810 #endif
812 // Shutdown xpcom. This will release all loaders and cause others holding
813 // a refcount to the component manager to release it.
814 if (nsComponentManagerImpl::gComponentManager) {
815 rv = (nsComponentManagerImpl::gComponentManager)->Shutdown();
816 NS_ASSERTION(NS_SUCCEEDED(rv), "Component Manager shutdown failed.");
817 } else
818 NS_WARNING("Component Manager was never created ...");
820 // Release our own singletons
821 // Do this _after_ shutting down the component manager, because the
822 // JS component loader will use XPConnect to call nsIModule::canUnload,
823 // and that will spin up the InterfaceInfoManager again -- bad mojo
824 xptiInterfaceInfoManager::FreeInterfaceInfoManager();
826 // Finally, release the component manager last because it unloads the
827 // libraries:
828 if (nsComponentManagerImpl::gComponentManager) {
829 nsrefcnt cnt;
830 NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt);
831 NS_ASSERTION(cnt == 0, "Component Manager being held past XPCOM shutdown.");
833 nsComponentManagerImpl::gComponentManager = nsnull;
835 #ifdef DEBUG
836 _FreeAutoLockStatics();
837 #endif
839 ShutdownSpecialSystemDirectory();
841 NS_PurgeAtomTable();
843 NS_IF_RELEASE(gDebug);
845 NS_LogTerm();
847 #ifdef GC_LEAK_DETECTOR
848 // Shutdown the Leak detector.
849 NS_ShutdownLeakDetector();
850 #endif
852 return NS_OK;