source: pkg/viola/main/xulrunner/branches/upstream/current/xpcom/build/nsXPComInit.cpp @ 4081

Revision 4081, 28.8 KB checked in by alanbach-guest, 6 years ago (diff)

[svn-inject] Installing original source of xulrunner

Line 
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 "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"
57
58#include "nsMemoryImpl.h"
59#include "nsDebugImpl.h"
60#include "nsTraceRefcntImpl.h"
61#include "nsErrorService.h"
62#include "nsByteBuffer.h"
63
64#include "nsSupportsArray.h"
65#include "nsArray.h"
66#include "nsINIParserImpl.h"
67#include "nsSupportsPrimitives.h"
68#include "nsConsoleService.h"
69#include "nsExceptionService.h"
70
71#include "nsComponentManager.h"
72#include "nsCategoryManagerUtils.h"
73#include "nsIServiceManager.h"
74#include "nsGenericFactory.h"
75
76#include "nsThreadManager.h"
77#include "nsThreadPool.h"
78
79#include "nsIProxyObjectManager.h"
80#include "nsProxyEventPrivate.h"  // access to the impl of nsProxyObjectManager for the generic factory registration.
81
82#include "xptinfo.h"
83#include "nsIInterfaceInfoManager.h"
84#include "xptiprivate.h"
85
86#include "nsTimerImpl.h"
87#include "TimerThread.h"
88
89#include "nsThread.h"
90#include "nsProcess.h"
91#include "nsEnvironment.h"
92#include "nsVersionComparatorImpl.h"
93
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"
104
105#include "nsStringStream.h"
106extern NS_METHOD nsStringInputStreamConstructor(nsISupports *, REFNSIID, void **);
107NS_DECL_CLASSINFO(nsStringInputStream)
108
109#include "nsFastLoadService.h"
110
111#include "nsAtomService.h"
112#include "nsAtomTable.h"
113#include "nsTraceRefcnt.h"
114#include "nsTimelineService.h"
115
116#include "nsHashPropertyBag.h"
117
118#include "nsUnicharInputStream.h"
119#include "nsVariant.h"
120
121#include "nsUUIDGenerator.h"
122
123#ifdef GC_LEAK_DETECTOR
124#include "nsLeakDetector.h"
125#endif
126#include "nsRecyclingAllocator.h"
127
128#include "SpecialSystemDirectory.h"
129
130#if defined(XP_WIN) && !defined(WINCE)
131#include "nsWindowsRegKey.h"
132#endif
133
134#ifdef XP_MACOSX
135#include "nsMacUtilsImpl.h"
136#endif
137
138#include "nsSystemInfo.h"
139#include "nsMemoryReporterManager.h"
140
141#include <locale.h>
142
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
148extern nsresult NS_RegistryGetFactory(nsIFactory** aFactory);
149extern nsresult NS_CategoryManagerGetFactory( nsIFactory** );
150
151#ifdef DEBUG
152extern void _FreeAutoLockStatics();
153#endif
154
155static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
156static NS_DEFINE_CID(kMemoryCID, NS_MEMORY_CID);
157static NS_DEFINE_CID(kINIParserFactoryCID, NS_INIPARSERFACTORY_CID);
158static NS_DEFINE_CID(kSimpleUnicharStreamFactoryCID, NS_SIMPLE_UNICHAR_STREAM_FACTORY_CID);
159
160NS_GENERIC_FACTORY_CONSTRUCTOR(nsProcess)
161
162#define NS_ENVIRONMENT_CLASSNAME "Environment Service"
163
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"
183
184NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsIDImpl)
185NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsStringImpl)
186NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsCStringImpl)
187NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRBoolImpl)
188NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint8Impl)
189NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint16Impl)
190NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint32Impl)
191NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint64Impl)
192NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRTimeImpl)
193NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsCharImpl)
194NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt16Impl)
195NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt32Impl)
196NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt64Impl)
197NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsFloatImpl)
198NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsDoubleImpl)
199NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsVoidImpl)
200NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsInterfacePointerImpl)
201
202NS_GENERIC_FACTORY_CONSTRUCTOR(nsArray)
203NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsConsoleService, Init)
204NS_DECL_CLASSINFO(nsConsoleService)
205NS_GENERIC_FACTORY_CONSTRUCTOR(nsAtomService)
206NS_GENERIC_FACTORY_CONSTRUCTOR(nsExceptionService)
207NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimerImpl)
208NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryOutputStream)
209NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryInputStream)
210NS_GENERIC_FACTORY_CONSTRUCTOR(nsStorageStream)
211NS_GENERIC_FACTORY_CONSTRUCTOR(nsVersionComparatorImpl)
212
213NS_GENERIC_FACTORY_CONSTRUCTOR(nsVariant)
214
215NS_GENERIC_FACTORY_CONSTRUCTOR(nsRecyclingAllocatorImpl)
216
217#ifdef MOZ_TIMELINE
218NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimelineService)
219#endif
220
221NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHashPropertyBag, Init)
222
223NS_GENERIC_AGGREGATED_CONSTRUCTOR_INIT(nsProperties, Init)
224
225NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUUIDGenerator, Init)
226
227#ifdef XP_MACOSX
228NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacUtilsImpl)
229#endif
230
231NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemInfo, Init)
232
233NS_GENERIC_FACTORY_CONSTRUCTOR(nsMemoryReporterManager)
234
235static NS_METHOD
236nsThreadManagerGetSingleton(nsISupports* outer,
237                            const nsIID& aIID,
238                            void* *aInstancePtr)
239{
240    NS_ASSERTION(aInstancePtr, "null outptr");
241    NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION);
242
243    return nsThreadManager::get()->QueryInterface(aIID, aInstancePtr);
244}
245NS_DECL_CLASSINFO(nsThreadManager)
246
247NS_GENERIC_FACTORY_CONSTRUCTOR(nsThreadPool)
248NS_DECL_CLASSINFO(nsThreadPool)
249
250static NS_METHOD
251nsXPTIInterfaceInfoManagerGetSingleton(nsISupports* outer,
252                                       const nsIID& aIID,
253                                       void* *aInstancePtr)
254{
255    NS_ASSERTION(aInstancePtr, "null outptr");
256    NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION);
257
258    nsCOMPtr<nsIInterfaceInfoManager> iim
259        (xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef());
260    if (!iim)
261        return NS_ERROR_FAILURE;
262
263    return iim->QueryInterface(aIID, aInstancePtr);
264}
265
266
267PR_STATIC_CALLBACK(nsresult)
268RegisterGenericFactory(nsIComponentRegistrar* registrar,
269                       const nsModuleComponentInfo *info)
270{
271    nsresult rv;
272    nsIGenericFactory* fact;
273    rv = NS_NewGenericFactory(&fact, info);
274    if (NS_FAILED(rv)) return rv;
275
276    rv = registrar->RegisterFactory(info->mCID, 
277                                    info->mDescription,
278                                    info->mContractID, 
279                                    fact);
280    NS_RELEASE(fact);
281    return rv;
282}
283
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.
289static PRBool CheckUpdateFile()
290{
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));
296
297    if (NS_FAILED(rv)) {
298        NS_WARNING("Getting NS_XPCOM_CURRENT_PROCESS_DIR failed");
299        return PR_FALSE;
300    }
301
302    file->AppendNative(nsDependentCString(".autoreg"));
303   
304    PRBool exists;
305    file->Exists(&exists);
306    if (!exists)
307        return PR_FALSE;
308
309    nsCOMPtr<nsIFile> compregFile;
310    rv = nsDirectoryService::gService->Get(NS_XPCOM_COMPONENT_REGISTRY_FILE,
311                                           NS_GET_IID(nsIFile),
312                                           getter_AddRefs(compregFile));
313
314   
315    if (NS_FAILED(rv)) {
316        NS_WARNING("Getting NS_XPCOM_COMPONENT_REGISTRY_FILE failed");
317        return PR_FALSE;
318    }
319
320    if (NS_FAILED(compregFile->Exists(&exists)) || !exists)
321        return PR_TRUE;
322
323    PRInt64 compregModTime, autoregModTime;
324    compregFile->GetLastModifiedTime(&compregModTime);
325    file->GetLastModifiedTime(&autoregModTime);
326
327    return LL_CMP(autoregModTime, >, compregModTime);
328}
329
330
331nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = NULL;
332PRBool gXPCOMShuttingDown = PR_FALSE;
333
334// For each class that wishes to support nsIClassInfo, add a line like this
335// NS_DECL_CLASSINFO(nsMyClass)
336
337#define COMPONENT(NAME, Ctor)                                                  \
338 { NS_##NAME##_CLASSNAME, NS_##NAME##_CID, NS_##NAME##_CONTRACTID, Ctor }
339
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) }
344
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 }
349
350static 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),
355
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),
363
364#define NS_PROPERTIES_CLASSNAME  "Properties"
365    COMPONENT(PROPERTIES, nsPropertiesConstructor),
366
367#define NS_PERSISTENTPROPERTIES_CID NS_IPERSISTENTPROPERTIES_CID /* sigh */
368    COMPONENT(PERSISTENTPROPERTIES, nsPersistentProperties::Create),
369
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),
382
383#define NS_XPCOMPROXY_CID NS_PROXYEVENT_MANAGER_CID
384    COMPONENT(XPCOMPROXY, nsProxyObjectManager::Create),
385
386    COMPONENT(TIMER, nsTimerImplConstructor),
387
388#define COMPONENT_SUPPORTS(TYPE, Type)                                         \
389  COMPONENT(SUPPORTS_##TYPE, nsSupports##Type##ImplConstructor)
390
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),
408
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),
416
417    COMPONENT_CI_FLAGS(THREADMANAGER, nsThreadManagerGetSingleton,
418                       nsThreadManager,
419                       nsIClassInfo::THREADSAFE | nsIClassInfo::SINGLETON),
420    COMPONENT_CI_FLAGS(THREADPOOL, nsThreadPoolConstructor,
421                       nsThreadPool, nsIClassInfo::THREADSAFE),
422
423    COMPONENT_CI_FLAGS(STRINGINPUTSTREAM, nsStringInputStreamConstructor,
424                       nsStringInputStream, nsIClassInfo::THREADSAFE),
425    COMPONENT(MULTIPLEXINPUTSTREAM, nsMultiplexInputStreamConstructor),
426
427#ifndef MOZ_NO_FAST_LOAD
428    COMPONENT(FASTLOADSERVICE, nsFastLoadService::Create),
429#endif
430
431    COMPONENT(VARIANT, nsVariantConstructor),
432    COMPONENT(INTERFACEINFOMANAGER_SERVICE, nsXPTIInterfaceInfoManagerGetSingleton),
433
434    COMPONENT(RECYCLINGALLOCATOR, nsRecyclingAllocatorImplConstructor),
435
436#define NS_HASH_PROPERTY_BAG_CLASSNAME "Hashtable Property Bag"
437    COMPONENT(HASH_PROPERTY_BAG, nsHashPropertyBagConstructor),
438
439    COMPONENT(UUID_GENERATOR, nsUUIDGeneratorConstructor),
440
441#if defined(XP_WIN) && !defined(WINCE)
442    COMPONENT(WINDOWSREGKEY, nsWindowsRegKeyConstructor),
443#endif
444
445#ifdef XP_MACOSX
446    COMPONENT(MACUTILSIMPL, nsMacUtilsImplConstructor),
447#endif
448
449    COMPONENT(SYSTEMINFO, nsSystemInfoConstructor),
450#define NS_MEMORY_REPORTER_MANAGER_CLASSNAME "Memory Reporter Manager"
451    COMPONENT(MEMORY_REPORTER_MANAGER, nsMemoryReporterManagerConstructor),
452};
453
454#undef COMPONENT
455
456const int components_length = sizeof(components) / sizeof(components[0]);
457
458// gDebug will be freed during shutdown.
459static nsIDebug* gDebug = nsnull;
460
461EXPORT_XPCOM_API(nsresult)
462NS_GetDebug(nsIDebug** result)
463{
464    return nsDebugImpl::Create(nsnull, 
465                               NS_GET_IID(nsIDebug), 
466                               (void**) result);
467}
468
469EXPORT_XPCOM_API(nsresult)
470NS_GetTraceRefcnt(nsITraceRefcnt** result)
471{
472    return nsTraceRefcntImpl::Create(nsnull, 
473                                     NS_GET_IID(nsITraceRefcnt), 
474                                     (void**) result);
475}
476
477EXPORT_XPCOM_API(nsresult)
478NS_InitXPCOM(nsIServiceManager* *result,
479                             nsIFile* binDirectory)
480{
481    return NS_InitXPCOM3(result, binDirectory, nsnull, nsnull, 0);
482}
483
484EXPORT_XPCOM_API(nsresult)
485NS_InitXPCOM2(nsIServiceManager* *result,
486                              nsIFile* binDirectory,
487                              nsIDirectoryServiceProvider* appFileLocationProvider)
488{
489    return NS_InitXPCOM3(result, binDirectory, appFileLocationProvider, nsnull, 0);
490}
491
492EXPORT_XPCOM_API(nsresult)
493NS_InitXPCOM3(nsIServiceManager* *result,
494                              nsIFile* binDirectory,
495                              nsIDirectoryServiceProvider* appFileLocationProvider,
496                              nsStaticModuleInfo const *staticComponents,
497                              PRUint32 componentCount)
498{
499    nsresult rv = NS_OK;
500
501#ifdef MOZ_ENABLE_LIBXUL
502    if (!staticComponents) {
503        staticComponents = kPStaticModules;
504        componentCount = kStaticModuleCount;
505    }
506#endif
507
508     // We are not shutting down
509    gXPCOMShuttingDown = PR_FALSE;
510
511    NS_LogInit();
512
513    // Establish the main thread here.
514    rv = nsThreadManager::get()->Init();
515    if (NS_FAILED(rv)) return rv;
516
517    // Set up the timer globals/timer thread
518    rv = nsTimerImpl::Startup();
519    NS_ENSURE_SUCCESS(rv, rv);
520
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
527
528#if defined(XP_UNIX) || defined(XP_OS2)
529    NS_StartupNativeCharsetUtils();
530#endif
531    NS_StartupLocalFile();
532
533    StartupSpecialSystemDirectory();
534
535    rv = nsDirectoryService::RealInit();
536    if (NS_FAILED(rv))
537        return rv;
538
539    nsCOMPtr<nsIFile> xpcomLib;
540           
541    PRBool value;
542    if (binDirectory)
543    {
544        rv = binDirectory->IsDirectory(&value);
545
546        if (NS_SUCCEEDED(rv) && value) {
547            nsDirectoryService::gService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, binDirectory);
548            binDirectory->Clone(getter_AddRefs(xpcomLib));
549        }
550    }
551    else {
552        nsDirectoryService::gService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, 
553                                          NS_GET_IID(nsIFile), 
554                                          getter_AddRefs(xpcomLib));
555    }
556
557    if (xpcomLib) {
558        xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL));
559        nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);
560    }
561   
562    if (appFileLocationProvider) {
563        rv = nsDirectoryService::gService->RegisterProvider(appFileLocationProvider);
564        if (NS_FAILED(rv)) return rv;
565    }
566
567    NS_ASSERTION(nsComponentManagerImpl::gComponentManager == NULL, "CompMgr not null at init");
568
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);
574   
575    rv = compMgr->Init(staticComponents, componentCount);
576    if (NS_FAILED(rv))
577    {
578        NS_RELEASE(compMgr);
579        return rv;
580    }
581
582    nsComponentManagerImpl::gComponentManager = compMgr;
583
584    if (result) {
585        nsIServiceManager *serviceManager =
586            static_cast<nsIServiceManager*>(compMgr);
587
588        NS_ADDREF(*result = serviceManager);
589    }
590
591    nsCOMPtr<nsIMemory> memory;
592    NS_GetMemoryManager(getter_AddRefs(memory));
593    rv = compMgr->RegisterService(kMemoryCID, memory);
594    if (NS_FAILED(rv)) return rv;
595
596    rv = compMgr->RegisterService(kComponentManagerCID, static_cast<nsIComponentManager*>(compMgr));
597    if (NS_FAILED(rv)) return rv;
598
599#ifdef GC_LEAK_DETECTOR
600    rv = NS_InitLeakDetector();
601    if (NS_FAILED(rv)) return rv;
602#endif
603
604    rv = nsCycleCollector_startup();
605    if (NS_FAILED(rv)) return rv;
606
607    // 2. Register the global services with the component manager so that
608    //    clients can create new objects.
609
610    // Category Manager
611    {
612      nsCOMPtr<nsIFactory> categoryManagerFactory;
613      if ( NS_FAILED(rv = NS_CategoryManagerGetFactory(getter_AddRefs(categoryManagerFactory))) )
614        return rv;
615
616      NS_DEFINE_CID(kCategoryManagerCID, NS_CATEGORYMANAGER_CID);
617
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;
624    }
625
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]);
631
632        nsCOMPtr<nsIFactory> iniParserFactory(new nsINIParserFactory());
633        if (iniParserFactory)
634            registrar->RegisterFactory(kINIParserFactoryCID, 
635                                       "nsINIParserFactory",
636                                       NS_INIPARSERFACTORY_CONTRACTID, 
637                                       iniParserFactory);
638
639        registrar->
640          RegisterFactory(kSimpleUnicharStreamFactoryCID,
641                          "nsSimpleUnicharStreamFactory",
642                          NS_SIMPLE_UNICHAR_STREAM_FACTORY_CONTRACTID,
643                          nsSimpleUnicharStreamFactory::GetInstance());
644    }
645
646    // Pay the cost at startup time of starting this singleton.
647    nsIInterfaceInfoManager* iim =
648        xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef();
649
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);
656    }
657
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();
662
663    // Initialize memory flusher
664    nsMemoryImpl::InitFlusher();
665
666    // Notify observers of xpcom autoregistration start
667    NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_CATEGORY, 
668                                  nsnull,
669                                  NS_XPCOM_STARTUP_OBSERVER_ID);
670   
671    return NS_OK;
672}
673
674
675//
676// NS_ShutdownXPCOM()
677//
678// The shutdown sequence for xpcom would be
679//
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
695//
696EXPORT_XPCOM_API(nsresult)
697NS_ShutdownXPCOM(nsIServiceManager* servMgr)
698{
699    NS_ENSURE_STATE(NS_IsMainThread());
700
701    nsresult rv;
702    nsCOMPtr<nsISimpleEnumerator> moduleLoaders;
703
704    // Notify observers of xpcom shutting down
705    {
706        // Block it so that the COMPtr will get deleted before we hit
707        // servicemanager shutdown
708
709        nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
710        NS_ENSURE_STATE(thread);
711
712        nsRefPtr<nsObserverService> observerService;
713        CallGetService("@mozilla.org/observer-service;1",
714                       (nsObserverService**) getter_AddRefs(observerService));
715
716        if (observerService)
717        {
718            nsCOMPtr<nsIServiceManager> mgr;
719            rv = NS_GetServiceManager(getter_AddRefs(mgr));
720            if (NS_SUCCEEDED(rv))
721            {
722                (void) observerService->
723                    NotifyObservers(mgr, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
724                                    nsnull);
725            }
726        }
727
728        NS_ProcessPendingEvents(thread);
729
730        if (observerService)
731            (void) observerService->
732                NotifyObservers(nsnull, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID,
733                                nsnull);
734
735        NS_ProcessPendingEvents(thread);
736
737        // Shutdown the timer thread and all timers that might still be alive before
738        // shutting down the component manager
739        nsTimerImpl::Shutdown();
740
741        NS_ProcessPendingEvents(thread);
742
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();
747
748        NS_ProcessPendingEvents(thread);
749
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));
756
757            observerService->Shutdown();
758        }
759    }
760
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;
765
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);
772
773    // Shutdown global servicemanager
774    if (nsComponentManagerImpl::gComponentManager) {
775        nsComponentManagerImpl::gComponentManager->FreeServices();
776    }
777
778    nsProxyObjectManager::Shutdown();
779
780    // Release the directory service
781    NS_IF_RELEASE(nsDirectoryService::gService);
782
783    nsCycleCollector_shutdown();
784
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));
791
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
795
796            nsCOMPtr<nsIObserver> obs(do_QueryInterface(el));
797            if (obs)
798                (void) obs->Observe(nsnull,
799                                    NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID,
800                                    nsnull);
801        }
802
803        moduleLoaders = nsnull;
804    }
805
806    // Shutdown nsLocalFile string conversion
807    NS_ShutdownLocalFile();
808#ifdef XP_UNIX
809    NS_ShutdownNativeCharsetUtils();
810#endif
811
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 ...");
819
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();
825
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.");
832    }
833    nsComponentManagerImpl::gComponentManager = nsnull;
834
835#ifdef DEBUG
836    _FreeAutoLockStatics();
837#endif
838
839    ShutdownSpecialSystemDirectory();
840
841    NS_PurgeAtomTable();
842
843    NS_IF_RELEASE(gDebug);
844
845    NS_LogTerm();
846
847#ifdef GC_LEAK_DETECTOR
848    // Shutdown the Leak detector.
849    NS_ShutdownLeakDetector();
850#endif
851
852    return NS_OK;
853}
Note: See TracBrowser for help on using the repository browser.