1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
3
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
5
* The contents of this file are subject to the Netscape Public License
6
* Version 1.1 (the "License"); you may not use this file except in
7
* compliance with the License. You may obtain a copy of the License at
8
* http://www.mozilla.org/NPL/
10
* Software distributed under the License is distributed on an "AS IS" basis,
11
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
* for the specific language governing rights and limitations under the
15
* The Original Code is mozilla.org code.
17
* The Initial Developer of the Original Code is
18
* Netscape Communications Corporation.
19
* Portions created by the Initial Developer are Copyright (C) 1998
20
* the Initial Developer. All Rights Reserved.
24
* Alternatively, the contents of this file may be used under the terms of
25
* either the GNU General Public License Version 2 or later (the "GPL"), or
26
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27
* in which case the provisions of the GPL or the LGPL are applicable instead
28
* of those above. If you wish to allow use of your version of this file only
29
* under the terms of either the GPL or the LGPL, and not to allow others to
30
* use your version of this file under the terms of the NPL, indicate your
31
* decision by deleting the provisions above and replace them with the notice
32
* and other provisions required by the GPL or the LGPL. If you do not delete
33
* the provisions above, a recipient may use your version of this file under
34
* the terms of any one of the NPL, the GPL or the LGPL.
36
* ***** END LICENSE BLOCK ***** */
39
#include "nsXPCOMPrivate.h"
43
#include "nsObserverList.h"
44
#include "nsObserverService.h"
45
#include "nsProperties.h"
46
#include "nsIProperties.h"
47
#include "nsPersistentProperties.h"
48
#include "nsScriptableInputStream.h"
49
#include "nsBinaryStream.h"
50
#include "nsStorageStream.h"
52
#include "nsMemoryImpl.h"
53
#include "nsDebugImpl.h"
54
#include "nsTraceRefcntImpl.h"
55
#include "nsErrorService.h"
56
#include "nsByteBuffer.h"
58
#include "nsSupportsArray.h"
60
#include "nsSupportsPrimitives.h"
61
#include "nsConsoleService.h"
62
#include "nsExceptionService.h"
64
#include "nsComponentManager.h"
65
#include "nsCategoryManagerUtils.h"
66
#include "nsIServiceManager.h"
67
#include "nsGenericFactory.h"
69
#include "nsEventQueueService.h"
70
#include "nsEventQueue.h"
72
#include "nsIProxyObjectManager.h"
73
#include "nsProxyEventPrivate.h" // access to the impl of nsProxyObjectManager for the generic factory registration.
76
#include "nsIInterfaceInfoManager.h"
78
#include "nsTimerImpl.h"
79
#include "TimerThread.h"
82
#include "nsProcess.h"
83
#include "nsEnvironment.h"
85
#include "nsEmptyEnumerator.h"
87
#include "nsILocalFile.h"
88
#include "nsLocalFile.h"
89
#if defined(XP_UNIX) || defined(XP_OS2)
90
#include "nsNativeCharsetUtils.h"
92
#include "nsDirectoryService.h"
93
#include "nsDirectoryServiceDefs.h"
94
#include "nsCategoryManager.h"
95
#include "nsICategoryManager.h"
96
#include "nsStringStream.h"
97
#include "nsMultiplexInputStream.h"
99
#include "nsFastLoadService.h"
101
#include "nsAtomService.h"
102
#include "nsAtomTable.h"
103
#include "nsTraceRefcnt.h"
104
#include "nsTimelineService.h"
106
#include "nsVariant.h"
108
#ifdef GC_LEAK_DETECTOR
109
#include "nsLeakDetector.h"
111
#include "nsRecyclingAllocator.h"
113
#include "SpecialSystemDirectory.h"
115
// Registry Factory creation function defined in nsRegistry.cpp
116
// We hook into this function locally to create and register the registry
117
// Since noone outside xpcom needs to know about this and nsRegistry.cpp
118
// does not have a local include file, we are putting this definition
119
// here rather than in nsIRegistry.h
120
extern nsresult NS_RegistryGetFactory(nsIFactory** aFactory);
121
extern nsresult NS_CategoryManagerGetFactory( nsIFactory** );
124
extern void _FreeAutoLockStatics();
127
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
128
static NS_DEFINE_CID(kMemoryCID, NS_MEMORY_CID);
129
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
131
NS_GENERIC_FACTORY_CONSTRUCTOR(nsProcess)
132
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsEventQueueServiceImpl, Init)
134
#define NS_ENVIRONMENT_CLASSNAME "Environment Service"
137
// ds/nsISupportsPrimitives
138
#define NS_SUPPORTS_ID_CLASSNAME "Supports ID"
139
#define NS_SUPPORTS_CSTRING_CLASSNAME "Supports String"
140
#define NS_SUPPORTS_STRING_CLASSNAME "Supports WString"
141
#define NS_SUPPORTS_PRBOOL_CLASSNAME "Supports PRBool"
142
#define NS_SUPPORTS_PRUINT8_CLASSNAME "Supports PRUint8"
143
#define NS_SUPPORTS_PRUINT16_CLASSNAME "Supports PRUint16"
144
#define NS_SUPPORTS_PRUINT32_CLASSNAME "Supports PRUint32"
145
#define NS_SUPPORTS_PRUINT64_CLASSNAME "Supports PRUint64"
146
#define NS_SUPPORTS_PRTIME_CLASSNAME "Supports PRTime"
147
#define NS_SUPPORTS_CHAR_CLASSNAME "Supports Char"
148
#define NS_SUPPORTS_PRINT16_CLASSNAME "Supports PRInt16"
149
#define NS_SUPPORTS_PRINT32_CLASSNAME "Supports PRInt32"
150
#define NS_SUPPORTS_PRINT64_CLASSNAME "Supports PRInt64"
151
#define NS_SUPPORTS_FLOAT_CLASSNAME "Supports float"
152
#define NS_SUPPORTS_DOUBLE_CLASSNAME "Supports double"
153
#define NS_SUPPORTS_VOID_CLASSNAME "Supports void"
154
#define NS_SUPPORTS_INTERFACE_POINTER_CLASSNAME "Supports interface pointer"
156
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsIDImpl)
157
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsStringImpl)
158
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsCStringImpl)
159
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRBoolImpl)
160
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint8Impl)
161
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint16Impl)
162
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint32Impl)
163
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint64Impl)
164
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRTimeImpl)
165
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsCharImpl)
166
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt16Impl)
167
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt32Impl)
168
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt64Impl)
169
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsFloatImpl)
170
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsDoubleImpl)
171
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsVoidImpl)
172
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsInterfacePointerImpl)
174
NS_GENERIC_FACTORY_CONSTRUCTOR(nsArray)
175
NS_GENERIC_FACTORY_CONSTRUCTOR(nsConsoleService)
176
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAtomService)
177
NS_GENERIC_FACTORY_CONSTRUCTOR(nsExceptionService)
178
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimerImpl)
179
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimerManager)
180
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryOutputStream)
181
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryInputStream)
182
NS_GENERIC_FACTORY_CONSTRUCTOR(nsStorageStream)
184
NS_GENERIC_FACTORY_CONSTRUCTOR(nsVariant)
186
NS_GENERIC_FACTORY_CONSTRUCTOR(nsRecyclingAllocatorImpl)
189
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimelineService)
193
nsXPTIInterfaceInfoManagerGetSingleton(nsISupports* outer,
197
NS_ENSURE_ARG_POINTER(aInstancePtr);
198
NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION);
200
nsCOMPtr<nsIInterfaceInfoManager> iim(dont_AddRef(XPTI_GetInterfaceInfoManager()));
202
return NS_ERROR_FAILURE;
205
return iim->QueryInterface(aIID, aInstancePtr);
209
PR_STATIC_CALLBACK(nsresult)
210
RegisterGenericFactory(nsIComponentRegistrar* registrar,
211
const nsModuleComponentInfo *info)
214
nsIGenericFactory* fact;
215
rv = NS_NewGenericFactory(&fact, info);
216
if (NS_FAILED(rv)) return rv;
218
rv = registrar->RegisterFactory(info->mCID,
226
// In order to support the installer, we need
227
// to be told out of band if we should cause
228
// an autoregister. If the file ".autoreg" exists in the binary
229
// directory, we check its timestamp against the timestamp of the
230
// compreg.dat file. If the .autoreg file is newer, we autoregister.
231
static PRBool CheckUpdateFile()
234
nsCOMPtr<nsIProperties> directoryService;
235
nsDirectoryService::Create(nsnull,
236
NS_GET_IID(nsIProperties),
237
getter_AddRefs(directoryService));
239
if (!directoryService)
242
nsCOMPtr<nsIFile> file;
243
rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
245
getter_AddRefs(file));
248
NS_WARNING("Getting NS_XPCOM_CURRENT_PROCESS_DIR failed");
252
file->AppendNative(nsDependentCString(".autoreg"));
255
file->Exists(&exists);
259
nsCOMPtr<nsIFile> compregFile;
260
rv = directoryService->Get(NS_XPCOM_COMPONENT_REGISTRY_FILE,
262
getter_AddRefs(compregFile));
266
NS_WARNING("Getting NS_XPCOM_COMPONENT_REGISTRY_FILE failed");
270
// Don't need to check whether compreg exists; if it doesn't
271
// we won't even be here.
273
PRInt64 compregModTime, autoregModTime;
274
compregFile->GetLastModifiedTime(&compregModTime);
275
file->GetLastModifiedTime(&autoregModTime);
277
return LL_CMP(autoregModTime, >, compregModTime);
281
nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = NULL;
282
nsIProperties *gDirectoryService = NULL;
283
PRBool gXPCOMShuttingDown = PR_FALSE;
285
// If XPCOM is unloaded, we need a way to ensure that all statics have been
286
// reinitalized when reloading. Here we create a boolean which is initialized
287
// to true. During shutdown, this boolean with set to false. When we startup,
288
// this boolean will be checked and if the value is not true, startup will fail.
289
static PRBool gXPCOMHasGlobalsBeenInitalized = PR_TRUE;
291
// For each class that wishes to support nsIClassInfo, add a line like this
292
// NS_DECL_CLASSINFO(nsMyClass)
294
#define COMPONENT(NAME, Ctor) \
295
{ NS_##NAME##_CLASSNAME, NS_##NAME##_CID, NS_##NAME##_CONTRACTID, Ctor }
297
#define COMPONENT_CI(NAME, Ctor, Class) \
298
{ NS_##NAME##_CLASSNAME, NS_##NAME##_CID, NS_##NAME##_CONTRACTID, Ctor, \
299
NULL, NULL, NULL, NS_CI_INTERFACE_GETTER_NAME(Class), NULL, \
300
&NS_CLASSINFO_NAME(Class) }
302
static const nsModuleComponentInfo components[] = {
303
COMPONENT(MEMORY, nsMemoryImpl::Create),
304
COMPONENT(DEBUG, nsDebugImpl::Create),
305
#define NS_ERRORSERVICE_CLASSNAME NS_ERRORSERVICE_NAME
306
COMPONENT(ERRORSERVICE, nsErrorService::Create),
308
COMPONENT(BYTEBUFFER, ByteBufferImpl::Create),
309
COMPONENT(SCRIPTABLEINPUTSTREAM, nsScriptableInputStream::Create),
310
COMPONENT(BINARYINPUTSTREAM, nsBinaryInputStreamConstructor),
311
COMPONENT(BINARYOUTPUTSTREAM, nsBinaryOutputStreamConstructor),
312
COMPONENT(STORAGESTREAM, nsStorageStreamConstructor),
314
#define NS_PROPERTIES_CLASSNAME "Properties"
315
COMPONENT(PROPERTIES, nsProperties::Create),
317
#define NS_PERSISTENTPROPERTIES_CID NS_IPERSISTENTPROPERTIES_CID /* sigh */
318
COMPONENT(PERSISTENTPROPERTIES, nsPersistentProperties::Create),
320
COMPONENT(SUPPORTSARRAY, nsSupportsArray::Create),
321
COMPONENT(ARRAY, nsArrayConstructor),
322
COMPONENT(CONSOLESERVICE, nsConsoleServiceConstructor),
323
COMPONENT(EXCEPTIONSERVICE, nsExceptionServiceConstructor),
324
COMPONENT(ATOMSERVICE, nsAtomServiceConstructor),
326
COMPONENT(TIMELINESERVICE, nsTimelineServiceConstructor),
328
COMPONENT(OBSERVERSERVICE, nsObserverService::Create),
329
COMPONENT(GENERICFACTORY, nsGenericFactory::Create),
330
COMPONENT(EVENTQUEUESERVICE, nsEventQueueServiceImplConstructor),
331
COMPONENT(EVENTQUEUE, nsEventQueueImpl::Create),
332
COMPONENT(THREAD, nsThread::Create),
334
#define NS_XPCOMPROXY_CID NS_PROXYEVENT_MANAGER_CID
335
COMPONENT(XPCOMPROXY, nsProxyObjectManager::Create),
337
COMPONENT(TIMER, nsTimerImplConstructor),
338
COMPONENT(TIMERMANAGER, nsTimerManagerConstructor),
340
#define COMPONENT_SUPPORTS(TYPE, Type) \
341
COMPONENT(SUPPORTS_##TYPE, nsSupports##Type##ImplConstructor)
343
COMPONENT_SUPPORTS(ID, ID),
344
COMPONENT_SUPPORTS(STRING, String),
345
COMPONENT_SUPPORTS(CSTRING, CString),
346
COMPONENT_SUPPORTS(PRBOOL, PRBool),
347
COMPONENT_SUPPORTS(PRUINT8, PRUint8),
348
COMPONENT_SUPPORTS(PRUINT16, PRUint16),
349
COMPONENT_SUPPORTS(PRUINT32, PRUint32),
350
COMPONENT_SUPPORTS(PRUINT64, PRUint64),
351
COMPONENT_SUPPORTS(PRTIME, PRTime),
352
COMPONENT_SUPPORTS(CHAR, Char),
353
COMPONENT_SUPPORTS(PRINT16, PRInt16),
354
COMPONENT_SUPPORTS(PRINT32, PRInt32),
355
COMPONENT_SUPPORTS(PRINT64, PRInt64),
356
COMPONENT_SUPPORTS(FLOAT, Float),
357
COMPONENT_SUPPORTS(DOUBLE, Double),
358
COMPONENT_SUPPORTS(VOID, Void),
359
COMPONENT_SUPPORTS(INTERFACE_POINTER, InterfacePointer),
361
#undef COMPONENT_SUPPORTS
362
#define NS_LOCAL_FILE_CLASSNAME "Local File Specification"
363
COMPONENT(LOCAL_FILE, nsLocalFile::nsLocalFileConstructor),
364
#define NS_DIRECTORY_SERVICE_CLASSNAME "nsIFile Directory Service"
365
COMPONENT(DIRECTORY_SERVICE, nsDirectoryService::Create),
366
COMPONENT(PROCESS, nsProcessConstructor),
367
COMPONENT(ENVIRONMENT, nsEnvironment::Create),
369
COMPONENT(STRINGINPUTSTREAM, nsStringInputStreamConstructor),
370
COMPONENT(MULTIPLEXINPUTSTREAM, nsMultiplexInputStreamConstructor),
372
COMPONENT(FASTLOADSERVICE, nsFastLoadService::Create),
373
COMPONENT(VARIANT, nsVariantConstructor),
374
COMPONENT(INTERFACEINFOMANAGER_SERVICE, nsXPTIInterfaceInfoManagerGetSingleton),
376
COMPONENT(RECYCLINGALLOCATOR, nsRecyclingAllocatorImplConstructor),
381
const int components_length = sizeof(components) / sizeof(components[0]);
383
// gMemory will be freed during shutdown.
384
static nsIMemory* gMemory = nsnull;
385
nsresult NS_COM NS_GetMemoryManager(nsIMemory* *result)
390
rv = nsMemoryImpl::Create(nsnull,
391
NS_GET_IID(nsIMemory),
394
NS_IF_ADDREF(*result = gMemory);
398
// gDebug will be freed during shutdown.
399
static nsIDebug* gDebug = nsnull;
400
nsresult NS_COM NS_GetDebug(nsIDebug** result)
405
rv = nsDebugImpl::Create(nsnull,
406
NS_GET_IID(nsIDebug),
409
NS_IF_ADDREF(*result = gDebug);
413
#ifdef NS_BUILD_REFCNT_LOGGING
414
// gTraceRefcnt will be freed during shutdown.
415
static nsITraceRefcnt* gTraceRefcnt = nsnull;
418
nsresult NS_COM NS_GetTraceRefcnt(nsITraceRefcnt** result)
420
#ifdef NS_BUILD_REFCNT_LOGGING
424
rv = nsTraceRefcntImpl::Create(nsnull,
425
NS_GET_IID(nsITraceRefcnt),
426
(void**)&gTraceRefcnt);
428
NS_IF_ADDREF(*result = gTraceRefcnt);
431
return NS_ERROR_NOT_INITIALIZED;
435
nsresult NS_COM NS_InitXPCOM(nsIServiceManager* *result,
436
nsIFile* binDirectory)
438
return NS_InitXPCOM2(result, binDirectory, nsnull);
441
nsresult NS_COM NS_InitXPCOM2(nsIServiceManager* *result,
442
nsIFile* binDirectory,
443
nsIDirectoryServiceProvider* appFileLocationProvider)
446
if (!gXPCOMHasGlobalsBeenInitalized)
447
return NS_ERROR_NOT_INITIALIZED;
451
// We are not shutting down
452
gXPCOMShuttingDown = PR_FALSE;
454
#ifdef NS_BUILD_REFCNT_LOGGING
455
nsTraceRefcntImpl::Startup();
458
// Establish the main thread here.
459
rv = nsIThread::SetMainThread();
460
if (NS_FAILED(rv)) return rv;
462
// Startup the memory manager
463
rv = nsMemoryImpl::Startup();
464
if (NS_FAILED(rv)) return rv;
466
#if defined(XP_UNIX) || defined(XP_OS2)
467
NS_StartupNativeCharsetUtils();
469
NS_StartupLocalFile();
471
StartupSpecialSystemDirectory();
473
// Start the directory service so that the component manager init can use it.
474
rv = nsDirectoryService::Create(nsnull,
475
NS_GET_IID(nsIProperties),
476
(void**)&gDirectoryService);
480
nsCOMPtr<nsIDirectoryService> dirService = do_QueryInterface(gDirectoryService, &rv);
483
rv = dirService->Init();
487
// Create the Component/Service Manager
488
nsComponentManagerImpl *compMgr = NULL;
490
if (nsComponentManagerImpl::gComponentManager == NULL)
492
compMgr = new nsComponentManagerImpl();
494
return NS_ERROR_OUT_OF_MEMORY;
497
nsCOMPtr<nsIFile> xpcomLib;
502
rv = binDirectory->IsDirectory(&value);
504
if (NS_SUCCEEDED(rv) && value) {
505
gDirectoryService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, binDirectory);
506
binDirectory->Clone(getter_AddRefs(xpcomLib));
510
gDirectoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
512
getter_AddRefs(xpcomLib));
516
xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL));
517
gDirectoryService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);
520
if (appFileLocationProvider) {
521
rv = dirService->RegisterProvider(appFileLocationProvider);
522
if (NS_FAILED(rv)) return rv;
525
rv = compMgr->Init();
532
nsComponentManagerImpl::gComponentManager = compMgr;
535
nsIServiceManager *serviceManager =
536
NS_STATIC_CAST(nsIServiceManager*, compMgr);
538
NS_ADDREF(*result = serviceManager);
542
nsCOMPtr<nsIMemory> memory;
543
NS_GetMemoryManager(getter_AddRefs(memory));
544
// dougt - these calls will be moved into a new interface when nsIComponentManager is frozen.
545
rv = compMgr->RegisterService(kMemoryCID, memory);
546
if (NS_FAILED(rv)) return rv;
548
rv = compMgr->RegisterService(kComponentManagerCID, NS_STATIC_CAST(nsIComponentManager*, compMgr));
549
if (NS_FAILED(rv)) return rv;
551
#ifdef GC_LEAK_DETECTOR
552
rv = NS_InitLeakDetector();
553
if (NS_FAILED(rv)) return rv;
556
// 2. Register the global services with the component manager so that
557
// clients can create new objects.
561
nsCOMPtr<nsIFactory> categoryManagerFactory;
562
if ( NS_FAILED(rv = NS_CategoryManagerGetFactory(getter_AddRefs(categoryManagerFactory))) )
565
NS_DEFINE_CID(kCategoryManagerCID, NS_CATEGORYMANAGER_CID);
567
rv = compMgr->RegisterFactory(kCategoryManagerCID,
568
NS_CATEGORYMANAGER_CLASSNAME,
569
NS_CATEGORYMANAGER_CONTRACTID,
570
categoryManagerFactory,
572
if ( NS_FAILED(rv) ) return rv;
575
// what I want to do here is QI for a Component Registration Manager. Since this
576
// has not been invented yet, QI to the obsolete manager. Kids, don't do this at home.
577
nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(
578
NS_STATIC_CAST(nsIComponentManager*,compMgr), &rv);
580
for (int i = 0; i < components_length; i++)
581
RegisterGenericFactory(registrar, &components[i]);
583
rv = nsComponentManagerImpl::gComponentManager->ReadPersistentRegistry();
586
printf("No Persistent Registry Found.\n");
590
if ( NS_FAILED(rv) || CheckUpdateFile()) {
591
// if we find no persistent registry, we will try to autoregister
592
// the default components directory.
593
nsComponentManagerImpl::gComponentManager->AutoRegister(nsnull);
595
// If the application is using a GRE, then,
596
// auto register components in the GRE directory as well.
598
// The application indicates that it's using an GRE by
599
// returning a valid nsIFile when queried (via appFileLocProvider)
600
// for the NS_GRE_DIR atom as shown below
603
if ( appFileLocationProvider ) {
604
nsCOMPtr<nsIFile> greDir;
605
PRBool persistent = PR_TRUE;
607
appFileLocationProvider->GetFile(NS_GRE_DIR, &persistent, getter_AddRefs(greDir));
611
printf("start - Registering GRE components\n");
613
rv = gDirectoryService->Get(NS_GRE_COMPONENT_DIR,
615
getter_AddRefs(greDir));
617
NS_ERROR("Could not get GRE components directory!");
621
// If the GRE contains any loaders, we want to know about it so that we can cause another
622
// autoregistration of the applications component directory.
623
int loaderCount = nsComponentManagerImpl::gComponentManager->GetLoaderCount();
624
rv = nsComponentManagerImpl::gComponentManager->AutoRegister(greDir);
626
if (loaderCount != nsComponentManagerImpl::gComponentManager->GetLoaderCount())
627
nsComponentManagerImpl::gComponentManager->AutoRegisterNonNativeComponents(nsnull);
630
printf("end - Registering GRE components\n");
633
NS_ERROR("Could not AutoRegister GRE components");
640
// If additional component directories have been specified, then
641
// register them as well.
644
nsCOMPtr<nsISimpleEnumerator> dirList;
645
gDirectoryService->Get(NS_XPCOM_COMPONENT_DIR_LIST,
646
NS_GET_IID(nsISimpleEnumerator),
647
getter_AddRefs(dirList));
650
while (NS_SUCCEEDED(dirList->HasMoreElements(&hasMore)) && hasMore) {
651
nsCOMPtr<nsISupports> elem;
652
dirList->GetNext(getter_AddRefs(elem));
654
nsCOMPtr<nsIFile> dir = do_QueryInterface(elem);
656
nsComponentManagerImpl::gComponentManager->AutoRegister(dir);
658
// XXX should we worry about new component loaders being
659
// XXX defined by this process?
665
// Make sure the compreg file's mod time is current.
666
nsCOMPtr<nsIFile> compregFile;
667
rv = gDirectoryService->Get(NS_XPCOM_COMPONENT_REGISTRY_FILE,
669
getter_AddRefs(compregFile));
670
compregFile->SetLastModifiedTime(PR_Now() / 1000);
673
// Pay the cost at startup time of starting this singleton.
674
nsIInterfaceInfoManager* iim = XPTI_GetInterfaceInfoManager();
677
// Notify observers of xpcom autoregistration start
678
NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_OBSERVER_ID,
680
NS_XPCOM_STARTUP_OBSERVER_ID);
686
static nsVoidArray* gExitRoutines;
688
static void CallExitRoutines()
693
PRInt32 count = gExitRoutines->Count();
694
for (PRInt32 i = 0; i < count; i++) {
695
XPCOMExitRoutine func = (XPCOMExitRoutine) gExitRoutines->ElementAt(i);
698
gExitRoutines->Clear();
699
delete gExitRoutines;
700
gExitRoutines = nsnull;
704
NS_RegisterXPCOMExitRoutine(XPCOMExitRoutine exitRoutine, PRUint32 priority)
706
// priority are not used right now. It will need to be implemented as more
707
// classes are moved into the glue library --dougt
708
if (!gExitRoutines) {
709
gExitRoutines = new nsVoidArray();
710
if (!gExitRoutines) {
711
NS_WARNING("Failed to allocate gExitRoutines");
712
return NS_ERROR_FAILURE;
716
PRBool okay = gExitRoutines->AppendElement((void*)exitRoutine);
717
return okay ? NS_OK : NS_ERROR_FAILURE;
721
NS_UnregisterXPCOMExitRoutine(XPCOMExitRoutine exitRoutine)
724
return NS_ERROR_FAILURE;
726
PRBool okay = gExitRoutines->RemoveElement((void*)exitRoutine);
727
return okay ? NS_OK : NS_ERROR_FAILURE;
732
// NS_ShutdownXPCOM()
734
// The shutdown sequence for xpcom would be
736
// - Release the Global Service Manager
737
// - Release all service instances held by the global service manager
738
// - Release the Global Service Manager itself
739
// - Release the Component Manager
740
// - Release all factories cached by the Component Manager
741
// - Unload Libraries
742
// - Release Contractid Cache held by Component Manager
743
// - Release dll abstraction held by Component Manager
744
// - Release the Registry held by Component Manager
745
// - Finally, release the component manager itself
747
nsresult NS_COM NS_ShutdownXPCOM(nsIServiceManager* servMgr)
750
// Notify observers of xpcom shutting down
753
// Block it so that the COMPtr will get deleted before we hit
754
// servicemanager shutdown
755
nsCOMPtr<nsIObserverService> observerService =
756
do_GetService("@mozilla.org/observer-service;1", &rv);
757
if (NS_SUCCEEDED(rv))
759
nsCOMPtr<nsIServiceManager> mgr;
760
rv = NS_GetServiceManager(getter_AddRefs(mgr));
761
if (NS_SUCCEEDED(rv))
763
(void) observerService->NotifyObservers(mgr,
764
NS_XPCOM_SHUTDOWN_OBSERVER_ID,
770
// grab the event queue so that we can process events one last time before exiting
771
nsCOMPtr <nsIEventQueue> currentQ;
773
nsCOMPtr<nsIEventQueueService> eventQService =
774
do_GetService(kEventQueueServiceCID, &rv);
777
eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(currentQ));
780
// XPCOM is officially in shutdown mode NOW
781
// Set this only after the observers have been notified as this
782
// will cause servicemanager to become inaccessible.
783
gXPCOMShuttingDown = PR_TRUE;
786
fprintf(stderr, "* * * * XPCOM shutdown. Access will be denied * * * * \n");
788
// We may have AddRef'd for the caller of NS_InitXPCOM, so release it
790
NS_IF_RELEASE(servMgr);
792
// Shutdown global servicemanager
793
if (nsComponentManagerImpl::gComponentManager) {
794
nsComponentManagerImpl::gComponentManager->FreeServices();
796
nsServiceManager::ShutdownGlobalServiceManager(nsnull);
799
currentQ->ProcessPendingEvents();
803
nsProxyObjectManager::Shutdown();
805
// Release the directory service
806
NS_IF_RELEASE(gDirectoryService);
808
// Shutdown nsLocalFile string conversion
809
NS_ShutdownLocalFile();
811
NS_ShutdownNativeCharsetUtils();
814
// Shutdown the timer thread and all timers that might still be alive before
815
// shutting down the component manager
816
nsTimerImpl::Shutdown();
820
// Shutdown xpcom. This will release all loaders and cause others holding
821
// a refcount to the component manager to release it.
822
if (nsComponentManagerImpl::gComponentManager) {
823
rv = (nsComponentManagerImpl::gComponentManager)->Shutdown();
824
NS_ASSERTION(NS_SUCCEEDED(rv), "Component Manager shutdown failed.");
826
NS_WARNING("Component Manager was never created ...");
828
// Release our own singletons
829
// Do this _after_ shutting down the component manager, because the
830
// JS component loader will use XPConnect to call nsIModule::canUnload,
831
// and that will spin up the InterfaceInfoManager again -- bad mojo
832
XPTI_FreeInterfaceInfoManager();
834
// Finally, release the component manager last because it unloads the
836
if (nsComponentManagerImpl::gComponentManager) {
838
NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt);
839
NS_WARN_IF_FALSE(cnt == 0, "Component Manager being held past XPCOM shutdown.");
841
nsComponentManagerImpl::gComponentManager = nsnull;
844
_FreeAutoLockStatics();
847
ShutdownSpecialSystemDirectory();
849
EmptyEnumeratorImpl::Shutdown();
850
nsMemoryImpl::Shutdown();
851
NS_IF_RELEASE(gMemory);
853
nsThread::Shutdown();
856
NS_IF_RELEASE(gDebug);
858
#ifdef NS_BUILD_REFCNT_LOGGING
859
nsTraceRefcntImpl::DumpStatistics();
860
nsTraceRefcntImpl::ResetStatistics();
861
nsTraceRefcntImpl::Shutdown();
864
#ifdef GC_LEAK_DETECTOR
865
// Shutdown the Leak detector.
866
NS_ShutdownLeakDetector();
869
gXPCOMHasGlobalsBeenInitalized = PR_FALSE;
873
#define GET_FUNC(_tag, _decl, _name) \
874
functions->_tag = (_decl) PR_FindSymbol(xpcomLib, _name); \
875
if (!functions->_tag) goto end
877
nsresult NS_COM PR_CALLBACK
878
NS_GetFrozenFunctions(XPCOMFunctions *functions, const char* libraryPath)
881
return NS_ERROR_OUT_OF_MEMORY;
883
if (functions->version != XPCOM_GLUE_VERSION)
884
return NS_ERROR_FAILURE;
886
PRLibrary *xpcomLib = PR_LoadLibrary(libraryPath);
888
return NS_ERROR_FAILURE;
890
nsresult rv = NS_ERROR_FAILURE;
892
GET_FUNC(init, InitFunc, "NS_InitXPCOM2");
893
GET_FUNC(shutdown, ShutdownFunc, "NS_ShutdownXPCOM");
894
GET_FUNC(getServiceManager, GetServiceManagerFunc, "NS_GetServiceManager");
895
GET_FUNC(getComponentManager, GetComponentManagerFunc, "NS_GetComponentManager");
896
GET_FUNC(getComponentRegistrar, GetComponentRegistrarFunc, "NS_GetComponentRegistrar");
897
GET_FUNC(getMemoryManager, GetMemoryManagerFunc, "NS_GetMemoryManager");
898
GET_FUNC(newLocalFile, NewLocalFileFunc, "NS_NewLocalFile");
899
GET_FUNC(newNativeLocalFile, NewNativeLocalFileFunc, "NS_NewNativeLocalFile");
900
GET_FUNC(registerExitRoutine, RegisterXPCOMExitRoutineFunc, "NS_RegisterXPCOMExitRoutine");
901
GET_FUNC(unregisterExitRoutine, UnregisterXPCOMExitRoutineFunc, "NS_UnregisterXPCOMExitRoutine");
903
// these functions were added post 1.4 (need to check size of |functions|)
904
if (functions->size > offsetof(XPCOMFunctions, getTraceRefcnt)) {
905
GET_FUNC(getDebug, GetDebugFunc, "NS_GetDebug");
906
GET_FUNC(getTraceRefcnt, GetTraceRefcntFunc, "NS_GetTraceRefcnt");
909
// these functions were added post 1.6 (need to check size of |functions|)
910
if (functions->size > offsetof(XPCOMFunctions, cstringCloneData)) {
911
GET_FUNC(stringContainerInit, StringContainerInitFunc, "NS_StringContainerInit");
912
GET_FUNC(stringContainerFinish, StringContainerFinishFunc, "NS_StringContainerFinish");
913
GET_FUNC(stringGetData, StringGetDataFunc, "NS_StringGetData");
914
GET_FUNC(stringSetData, StringSetDataFunc, "NS_StringSetData");
915
GET_FUNC(stringSetDataRange, StringSetDataRangeFunc, "NS_StringSetDataRange");
916
GET_FUNC(stringCopy, StringCopyFunc, "NS_StringCopy");
917
GET_FUNC(cstringContainerInit, CStringContainerInitFunc, "NS_CStringContainerInit");
918
GET_FUNC(cstringContainerFinish, CStringContainerFinishFunc, "NS_CStringContainerFinish");
919
GET_FUNC(cstringGetData, CStringGetDataFunc, "NS_CStringGetData");
920
GET_FUNC(cstringSetData, CStringSetDataFunc, "NS_CStringSetData");
921
GET_FUNC(cstringSetDataRange, CStringSetDataRangeFunc, "NS_CStringSetDataRange");
922
GET_FUNC(cstringCopy, CStringCopyFunc, "NS_CStringCopy");
923
GET_FUNC(cstringToUTF16, CStringToUTF16, "NS_CStringToUTF16");
924
GET_FUNC(utf16ToCString, UTF16ToCString, "NS_UTF16ToCString");
925
GET_FUNC(stringCloneData, StringCloneDataFunc, "NS_StringCloneData");
926
GET_FUNC(cstringCloneData, CStringCloneDataFunc, "NS_CStringCloneData");
931
PR_UnloadLibrary(xpcomLib); // the library is refcnt'ed above by the caller.