VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/xpcom/build/nsXPComInit.cpp@ 103140

最後變更 在這個檔案從103140是 103140,由 vboxsync 提交於 11 月 前

libs/xpcom: Some warning fixes about externally visible functions which should be static, bugref:3409

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 29.5 KB
 
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
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
13 * License.
14 *
15 * The Original Code is mozilla.org code.
16 *
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.
21 *
22 * Contributor(s):
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or 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 MPL, 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 MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38#include <iprt/initterm.h>
39#include <iprt/time.h>
40
41#include "nsXPCOM.h"
42#include "nsXPCOMPrivate.h"
43#include "nscore.h"
44#include "nsCOMPtr.h"
45#include "nsObserverList.h"
46#include "nsObserverService.h"
47#include "nsProperties.h"
48#include "nsIProperties.h"
49
50#include "nsDebugImpl.h"
51#include "nsTraceRefcntImpl.h"
52#include "nsErrorService.h"
53
54#include "nsSupportsArray.h"
55#include "nsArray.h"
56#include "nsSupportsPrimitives.h"
57#include "nsExceptionService.h"
58
59#include "nsComponentManager.h"
60#include "nsCategoryManagerUtils.h"
61#include "nsIServiceManager.h"
62#include "nsGenericFactory.h"
63
64#include "nsEventQueueService.h"
65#include "nsEventQueue.h"
66#ifdef VBOX
67# include "nsEventQueueUtils.h"
68# include "nsProxyRelease.h"
69#endif /* VBOX */
70
71#include "nsIProxyObjectManager.h"
72#include "nsProxyEventPrivate.h" // access to the impl of nsProxyObjectManager for the generic factory registration.
73
74#include "xptinfo.h"
75#include "nsIInterfaceInfoManager.h"
76
77#include "nsEmptyEnumerator.h"
78
79#include "nsILocalFile.h"
80#include "nsLocalFile.h"
81#if defined(XP_UNIX) || defined(XP_OS2)
82#include "nsNativeCharsetUtils.h"
83#endif
84#include "nsDirectoryService.h"
85#include "nsDirectoryServiceDefs.h"
86#include "nsCategoryManager.h"
87#include "nsICategoryManager.h"
88
89#include "nsAtomService.h"
90#include "nsAtomTable.h"
91#include "nsTraceRefcnt.h"
92
93#include "nsVariant.h"
94
95#include "SpecialSystemDirectory.h"
96
97#include "ipcdclient.h"
98#include "ipcService.h"
99#include "ipcConfig.h"
100#include "ipcCID.h"
101#include "ipcLockService.h"
102#include "ipcLockCID.h"
103#include "tmTransactionService.h"
104#include "ipcDConnectService.h"
105
106#include <locale.h>
107
108// Registry Factory creation function defined in nsRegistry.cpp
109// We hook into this function locally to create and register the registry
110// Since noone outside xpcom needs to know about this and nsRegistry.cpp
111// does not have a local include file, we are putting this definition
112// here rather than in nsIRegistry.h
113extern nsresult NS_RegistryGetFactory(nsIFactory** aFactory);
114extern nsresult NS_CategoryManagerGetFactory( nsIFactory** );
115
116static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
117static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
118
119NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsEventQueueServiceImpl, Init)
120
121static RTTHREAD g_hMainThread = 0;
122
123#define NS_ENVIRONMENT_CLASSNAME "Environment Service"
124
125#include "nsXPCOM.h"
126// ds/nsISupportsPrimitives
127#define NS_SUPPORTS_ID_CLASSNAME "Supports ID"
128#define NS_SUPPORTS_CSTRING_CLASSNAME "Supports String"
129#define NS_SUPPORTS_STRING_CLASSNAME "Supports WString"
130#define NS_SUPPORTS_PRBOOL_CLASSNAME "Supports PRBool"
131#define NS_SUPPORTS_PRUINT8_CLASSNAME "Supports PRUint8"
132#define NS_SUPPORTS_PRUINT16_CLASSNAME "Supports PRUint16"
133#define NS_SUPPORTS_PRUINT32_CLASSNAME "Supports PRUint32"
134#define NS_SUPPORTS_PRUINT64_CLASSNAME "Supports PRUint64"
135#define NS_SUPPORTS_PRTIME_CLASSNAME "Supports PRTime"
136#define NS_SUPPORTS_CHAR_CLASSNAME "Supports Char"
137#define NS_SUPPORTS_PRINT16_CLASSNAME "Supports PRInt16"
138#define NS_SUPPORTS_PRINT32_CLASSNAME "Supports PRInt32"
139#define NS_SUPPORTS_PRINT64_CLASSNAME "Supports PRInt64"
140#define NS_SUPPORTS_FLOAT_CLASSNAME "Supports float"
141#define NS_SUPPORTS_DOUBLE_CLASSNAME "Supports double"
142#define NS_SUPPORTS_VOID_CLASSNAME "Supports void"
143#define NS_SUPPORTS_INTERFACE_POINTER_CLASSNAME "Supports interface pointer"
144
145NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsIDImpl)
146NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsStringImpl)
147NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsCStringImpl)
148NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRBoolImpl)
149NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint8Impl)
150NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint16Impl)
151NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint32Impl)
152NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRUint64Impl)
153NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRTimeImpl)
154NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsCharImpl)
155NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt16Impl)
156NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt32Impl)
157NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsPRInt64Impl)
158NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsFloatImpl)
159NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsDoubleImpl)
160NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsVoidImpl)
161NS_GENERIC_FACTORY_CONSTRUCTOR(nsSupportsInterfacePointerImpl)
162
163NS_GENERIC_FACTORY_CONSTRUCTOR(nsArray)
164NS_GENERIC_FACTORY_CONSTRUCTOR(nsAtomService)
165NS_GENERIC_FACTORY_CONSTRUCTOR(nsExceptionService)
166
167NS_GENERIC_FACTORY_CONSTRUCTOR(nsVariant)
168
169static NS_METHOD
170nsXPTIInterfaceInfoManagerGetSingleton(nsISupports* outer,
171 const nsIID& aIID,
172 void* *aInstancePtr)
173{
174 NS_ENSURE_ARG_POINTER(aInstancePtr);
175 NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION);
176
177 nsCOMPtr<nsIInterfaceInfoManager> iim(dont_AddRef(XPTI_GetInterfaceInfoManager()));
178 if (!iim) {
179 return NS_ERROR_FAILURE;
180 }
181
182 return iim->QueryInterface(aIID, aInstancePtr);
183}
184
185
186PR_STATIC_CALLBACK(nsresult)
187RegisterGenericFactory(nsIComponentRegistrar* registrar,
188 const nsModuleComponentInfo *info)
189{
190 nsresult rv;
191 nsIGenericFactory* fact;
192 rv = NS_NewGenericFactory(&fact, info);
193 if (NS_FAILED(rv)) return rv;
194
195 rv = registrar->RegisterFactory(info->mCID,
196 info->mDescription,
197 info->mContractID,
198 fact);
199 NS_RELEASE(fact);
200 return rv;
201}
202
203// In order to support the installer, we need
204// to be told out of band if we should cause
205// an autoregister. If the file ".autoreg" exists in the binary
206// directory, we check its timestamp against the timestamp of the
207// compreg.dat file. If the .autoreg file is newer, we autoregister.
208static PRBool CheckUpdateFile()
209{
210 nsresult rv;
211 nsCOMPtr<nsIProperties> directoryService;
212 nsDirectoryService::Create(nsnull,
213 NS_GET_IID(nsIProperties),
214 getter_AddRefs(directoryService));
215
216 if (!directoryService)
217 return PR_FALSE;
218
219 nsCOMPtr<nsIFile> file;
220 rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
221 NS_GET_IID(nsIFile),
222 getter_AddRefs(file));
223
224 if (NS_FAILED(rv)) {
225 NS_WARNING("Getting NS_XPCOM_CURRENT_PROCESS_DIR failed");
226 return PR_FALSE;
227 }
228
229 file->AppendNative(nsDependentCString(".autoreg"));
230
231 PRBool exists;
232 file->Exists(&exists);
233 if (!exists)
234 return PR_FALSE;
235
236 nsCOMPtr<nsIFile> compregFile;
237 rv = directoryService->Get(NS_XPCOM_COMPONENT_REGISTRY_FILE,
238 NS_GET_IID(nsIFile),
239 getter_AddRefs(compregFile));
240
241
242 if (NS_FAILED(rv)) {
243 NS_WARNING("Getting NS_XPCOM_COMPONENT_REGISTRY_FILE failed");
244 return PR_FALSE;
245 }
246
247 // Don't need to check whether compreg exists; if it doesn't
248 // we won't even be here.
249
250 PRInt64 compregModTime, autoregModTime;
251 compregFile->GetLastModifiedTime(&compregModTime);
252 file->GetLastModifiedTime(&autoregModTime);
253
254 return LL_CMP(autoregModTime, >, compregModTime);
255}
256
257#if 0 /// @todo later
258NS_GENERIC_FACTORY_CONSTRUCTOR(ipcService)
259NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(ipcLockService, Init)
260NS_GENERIC_FACTORY_CONSTRUCTOR(tmTransactionService)
261NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(ipcDConnectService, Init)
262
263// enable this code to make the IPC DCONNECT service auto-start.
264NS_METHOD
265ipcDConnectServiceRegisterProc(nsIComponentManager *aCompMgr,
266 nsIFile *aPath,
267 const char *registryLocation,
268 const char *componentType,
269 const nsModuleComponentInfo *info)
270{
271 //
272 // add ipcService to the XPCOM startup category
273 //
274 nsCOMPtr<nsICategoryManager> catman(do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
275 if (catman) {
276 nsXPIDLCString prevEntry;
277 catman->AddCategoryEntry(NS_XPCOM_STARTUP_OBSERVER_ID, "ipcDConnectService",
278 IPC_DCONNECTSERVICE_CONTRACTID, PR_TRUE, PR_TRUE,
279 getter_Copies(prevEntry));
280 }
281 return NS_OK;
282}
283
284NS_METHOD
285ipcDConnectServiceUnregisterProc(nsIComponentManager *aCompMgr,
286 nsIFile *aPath,
287 const char *registryLocation,
288 const nsModuleComponentInfo *info)
289{
290 nsCOMPtr<nsICategoryManager> catman(do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
291 if (catman)
292 catman->DeleteCategoryEntry(NS_XPCOM_STARTUP_OBSERVER_ID,
293 IPC_DCONNECTSERVICE_CONTRACTID, PR_TRUE);
294 return NS_OK;
295}
296#endif
297
298nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = NULL;
299nsIProperties *gDirectoryService = NULL;
300PRBool gXPCOMShuttingDown = PR_FALSE;
301#ifdef VBOX
302static PRBool gXPCOMInitialized = PR_FALSE;
303#endif
304
305// For each class that wishes to support nsIClassInfo, add a line like this
306// NS_DECL_CLASSINFO(nsMyClass)
307
308#define COMPONENT(NAME, Ctor) \
309 { NS_##NAME##_CLASSNAME, NS_##NAME##_CID, NS_##NAME##_CONTRACTID, Ctor }
310
311#define COMPONENT_CI(NAME, Ctor, Class) \
312 { NS_##NAME##_CLASSNAME, NS_##NAME##_CID, NS_##NAME##_CONTRACTID, Ctor, \
313 NULL, NULL, NULL, NS_CI_INTERFACE_GETTER_NAME(Class), NULL, \
314 &NS_CLASSINFO_NAME(Class) }
315
316static const nsModuleComponentInfo components[] = {
317 COMPONENT(DEBUG, nsDebugImpl::Create),
318#define NS_ERRORSERVICE_CLASSNAME NS_ERRORSERVICE_NAME
319 COMPONENT(ERRORSERVICE, nsErrorService::Create),
320
321#define NS_PROPERTIES_CLASSNAME "Properties"
322 COMPONENT(PROPERTIES, nsProperties::Create),
323
324 COMPONENT(SUPPORTSARRAY, nsSupportsArray::Create),
325 COMPONENT(ARRAY, nsArrayConstructor),
326 COMPONENT(EXCEPTIONSERVICE, nsExceptionServiceConstructor),
327 COMPONENT(ATOMSERVICE, nsAtomServiceConstructor),
328 COMPONENT(OBSERVERSERVICE, nsObserverService::Create),
329 COMPONENT(GENERICFACTORY, nsGenericFactory::Create),
330 COMPONENT(EVENTQUEUESERVICE, nsEventQueueServiceImplConstructor),
331 COMPONENT(EVENTQUEUE, nsEventQueueImpl::Create),
332
333#define NS_XPCOMPROXY_CID NS_PROXYEVENT_MANAGER_CID
334 COMPONENT(XPCOMPROXY, nsProxyObjectManager::Create),
335
336#define COMPONENT_SUPPORTS(TYPE, Type) \
337 COMPONENT(SUPPORTS_##TYPE, nsSupports##Type##ImplConstructor)
338
339 COMPONENT_SUPPORTS(ID, ID),
340 COMPONENT_SUPPORTS(STRING, String),
341 COMPONENT_SUPPORTS(CSTRING, CString),
342 COMPONENT_SUPPORTS(PRBOOL, PRBool),
343 COMPONENT_SUPPORTS(PRUINT8, PRUint8),
344 COMPONENT_SUPPORTS(PRUINT16, PRUint16),
345 COMPONENT_SUPPORTS(PRUINT32, PRUint32),
346 COMPONENT_SUPPORTS(PRUINT64, PRUint64),
347 COMPONENT_SUPPORTS(PRTIME, PRTime),
348 COMPONENT_SUPPORTS(CHAR, Char),
349 COMPONENT_SUPPORTS(PRINT16, PRInt16),
350 COMPONENT_SUPPORTS(PRINT32, PRInt32),
351 COMPONENT_SUPPORTS(PRINT64, PRInt64),
352 COMPONENT_SUPPORTS(FLOAT, Float),
353 COMPONENT_SUPPORTS(DOUBLE, Double),
354 COMPONENT_SUPPORTS(VOID, Void),
355 COMPONENT_SUPPORTS(INTERFACE_POINTER, InterfacePointer),
356
357#undef COMPONENT_SUPPORTS
358#define NS_LOCAL_FILE_CLASSNAME "Local File Specification"
359 COMPONENT(LOCAL_FILE, nsLocalFile::nsLocalFileConstructor),
360#define NS_DIRECTORY_SERVICE_CLASSNAME "nsIFile Directory Service"
361 COMPONENT(DIRECTORY_SERVICE, nsDirectoryService::Create),
362
363 COMPONENT(VARIANT, nsVariantConstructor),
364 COMPONENT(INTERFACEINFOMANAGER_SERVICE, nsXPTIInterfaceInfoManagerGetSingleton),
365
366#if 0 /// @todo later
367 { IPC_SERVICE_CLASSNAME,
368 IPC_SERVICE_CID,
369 IPC_SERVICE_CONTRACTID,
370 ipcServiceConstructor },
371 /*
372 ipcServiceRegisterProc,
373 ipcServiceUnregisterProc },
374 */
375 //
376 // extensions go here:
377 //
378 { IPC_LOCKSERVICE_CLASSNAME,
379 IPC_LOCKSERVICE_CID,
380 IPC_LOCKSERVICE_CONTRACTID,
381 ipcLockServiceConstructor },
382 { IPC_TRANSACTIONSERVICE_CLASSNAME,
383 IPC_TRANSACTIONSERVICE_CID,
384 IPC_TRANSACTIONSERVICE_CONTRACTID,
385 tmTransactionServiceConstructor },
386
387#ifdef BUILD_DCONNECT
388 { IPC_DCONNECTSERVICE_CLASSNAME,
389 IPC_DCONNECTSERVICE_CID,
390 IPC_DCONNECTSERVICE_CONTRACTID,
391 ipcDConnectServiceConstructor,
392 ipcDConnectServiceRegisterProc,
393 ipcDConnectServiceUnregisterProc },
394#endif
395#endif
396};
397
398#undef COMPONENT
399
400const int components_length = sizeof(components) / sizeof(components[0]);
401
402// gDebug will be freed during shutdown.
403static nsIDebug* gDebug = nsnull;
404nsresult NS_COM NS_GetDebug(nsIDebug** result)
405{
406 nsresult rv = NS_OK;
407 if (!gDebug)
408 {
409 rv = nsDebugImpl::Create(nsnull,
410 NS_GET_IID(nsIDebug),
411 (void**)&gDebug);
412 }
413 NS_IF_ADDREF(*result = gDebug);
414 return rv;
415}
416
417#ifdef NS_BUILD_REFCNT_LOGGING
418// gTraceRefcnt will be freed during shutdown.
419static nsITraceRefcnt* gTraceRefcnt = nsnull;
420#endif
421
422nsresult NS_COM NS_GetTraceRefcnt(nsITraceRefcnt** result)
423{
424#ifdef NS_BUILD_REFCNT_LOGGING
425 nsresult rv = NS_OK;
426 if (!gTraceRefcnt)
427 {
428 rv = nsTraceRefcntImpl::Create(nsnull,
429 NS_GET_IID(nsITraceRefcnt),
430 (void**)&gTraceRefcnt);
431 }
432 NS_IF_ADDREF(*result = gTraceRefcnt);
433 return rv;
434#else
435 return NS_ERROR_NOT_INITIALIZED;
436#endif
437}
438
439#ifdef VBOX
440PRBool NS_COM NS_IsXPCOMInitialized(void)
441{
442 return gXPCOMInitialized;
443}
444#endif
445
446nsresult NS_COM
447NS_GetMainThread(RTTHREAD *phThreadMain)
448{
449 NS_ASSERTION(phThreadMain, "bad result pointer");
450 if (g_hMainThread == NIL_RTTHREAD)
451 return NS_ERROR_FAILURE;
452 *phThreadMain = g_hMainThread;
453 return NS_OK;
454}
455
456nsresult NS_COM NS_InitXPCOM2(nsIServiceManager* *result,
457 nsIFile* binDirectory,
458 nsIDirectoryServiceProvider* appFileLocationProvider)
459{
460 nsresult rv = NS_OK;
461
462 /* Make sure IPRT is initialized. */
463 RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);
464
465 // We are not shutting down
466 gXPCOMShuttingDown = PR_FALSE;
467
468#ifdef NS_BUILD_REFCNT_LOGGING
469 nsTraceRefcntImpl::Startup();
470#endif
471
472 // Establish the main thread here.
473 g_hMainThread = RTThreadSelf();
474
475 // If the locale hasn't already been setup by our embedder,
476 // get us out of the "C" locale and into the system
477 if (strcmp(setlocale(LC_ALL, NULL), "C") == 0)
478 setlocale(LC_ALL, "");
479
480#if defined(XP_UNIX) || defined(XP_OS2)
481 NS_StartupNativeCharsetUtils();
482#endif
483 NS_StartupLocalFile();
484
485 StartupSpecialSystemDirectory();
486
487 // Start the directory service so that the component manager init can use it.
488 rv = nsDirectoryService::Create(nsnull,
489 NS_GET_IID(nsIProperties),
490 (void**)&gDirectoryService);
491 if (NS_FAILED(rv))
492 return rv;
493
494 nsCOMPtr<nsIDirectoryService> dirService = do_QueryInterface(gDirectoryService, &rv);
495 if (NS_FAILED(rv))
496 return rv;
497 rv = dirService->Init();
498 if (NS_FAILED(rv))
499 return rv;
500
501 // Create the Component/Service Manager
502 nsComponentManagerImpl *compMgr = NULL;
503
504 if (nsComponentManagerImpl::gComponentManager == NULL)
505 {
506 compMgr = new nsComponentManagerImpl();
507 if (compMgr == NULL)
508 return NS_ERROR_OUT_OF_MEMORY;
509 NS_ADDREF(compMgr);
510
511 nsCOMPtr<nsIFile> xpcomLib;
512
513 PRBool value;
514 if (binDirectory)
515 {
516 rv = binDirectory->IsDirectory(&value);
517
518 if (NS_SUCCEEDED(rv) && value) {
519 gDirectoryService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, binDirectory);
520 binDirectory->Clone(getter_AddRefs(xpcomLib));
521 }
522 }
523 else {
524 gDirectoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
525 NS_GET_IID(nsIFile),
526 getter_AddRefs(xpcomLib));
527 }
528
529 if (xpcomLib) {
530 xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL));
531 gDirectoryService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);
532 }
533
534 if (appFileLocationProvider) {
535 rv = dirService->RegisterProvider(appFileLocationProvider);
536 if (NS_FAILED(rv)) return rv;
537 }
538
539 rv = compMgr->Init();
540 if (NS_FAILED(rv))
541 {
542 NS_RELEASE(compMgr);
543 return rv;
544 }
545
546 nsComponentManagerImpl::gComponentManager = compMgr;
547
548 if (result) {
549 nsIServiceManager *serviceManager =
550 NS_STATIC_CAST(nsIServiceManager*, compMgr);
551
552 NS_ADDREF(*result = serviceManager);
553 }
554 }
555
556 rv = compMgr->RegisterService(kComponentManagerCID, NS_STATIC_CAST(nsIComponentManager*, compMgr));
557 if (NS_FAILED(rv)) return rv;
558
559 // 2. Register the global services with the component manager so that
560 // clients can create new objects.
561
562 // Category Manager
563 {
564 nsCOMPtr<nsIFactory> categoryManagerFactory;
565 if ( NS_FAILED(rv = NS_CategoryManagerGetFactory(getter_AddRefs(categoryManagerFactory))) )
566 return rv;
567
568 NS_DEFINE_CID(kCategoryManagerCID, NS_CATEGORYMANAGER_CID);
569
570 rv = compMgr->RegisterFactory(kCategoryManagerCID,
571 NS_CATEGORYMANAGER_CLASSNAME,
572 NS_CATEGORYMANAGER_CONTRACTID,
573 categoryManagerFactory,
574 PR_TRUE);
575 if ( NS_FAILED(rv) ) return rv;
576 }
577
578 // what I want to do here is QI for a Component Registration Manager. Since this
579 // has not been invented yet, QI to the obsolete manager. Kids, don't do this at home.
580 nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(
581 NS_STATIC_CAST(nsIComponentManager*,compMgr), &rv);
582 if (registrar) {
583 for (int i = 0; i < components_length; i++)
584 RegisterGenericFactory(registrar, &components[i]);
585 }
586 rv = nsComponentManagerImpl::gComponentManager->ReadPersistentRegistry();
587#ifdef DEBUG
588 if (NS_FAILED(rv)) {
589 printf("No Persistent Registry Found.\n");
590 }
591#endif
592
593#if 0 /// @todo later
594 rv = IPC_Init();
595 if (NS_FAILED(rv))
596 return rv;
597#endif
598
599 if ( NS_FAILED(rv) || CheckUpdateFile()) {
600 // if we find no persistent registry, we will try to autoregister
601 // the default components directory.
602 nsComponentManagerImpl::gComponentManager->AutoRegister(nsnull);
603
604 // If the application is using a GRE, then,
605 // auto register components in the GRE directory as well.
606 //
607 // The application indicates that it's using an GRE by
608 // returning a valid nsIFile when queried (via appFileLocProvider)
609 // for the NS_GRE_DIR atom as shown below
610 //
611
612 if ( appFileLocationProvider ) {
613 nsCOMPtr<nsIFile> greDir;
614 PRBool persistent = PR_TRUE;
615
616 appFileLocationProvider->GetFile(NS_GRE_DIR, &persistent, getter_AddRefs(greDir));
617
618 if (greDir) {
619#ifdef DEBUG_dougt
620 printf("start - Registering GRE components\n");
621#endif
622 rv = gDirectoryService->Get(NS_GRE_COMPONENT_DIR,
623 NS_GET_IID(nsIFile),
624 getter_AddRefs(greDir));
625 if (NS_FAILED(rv)) {
626 NS_ERROR("Could not get GRE components directory!");
627 return rv;
628 }
629
630 // If the GRE contains any loaders, we want to know about it so that we can cause another
631 // autoregistration of the applications component directory.
632 int loaderCount = nsComponentManagerImpl::gComponentManager->GetLoaderCount();
633 rv = nsComponentManagerImpl::gComponentManager->AutoRegister(greDir);
634
635 if (loaderCount != nsComponentManagerImpl::gComponentManager->GetLoaderCount())
636 nsComponentManagerImpl::gComponentManager->AutoRegisterNonNativeComponents(nsnull);
637
638#ifdef DEBUG_dougt
639 printf("end - Registering GRE components\n");
640#endif
641 if (NS_FAILED(rv)) {
642 NS_ERROR("Could not AutoRegister GRE components");
643 return rv;
644 }
645 }
646 }
647
648 //
649 // If additional component directories have been specified, then
650 // register them as well.
651 //
652
653 nsCOMPtr<nsISimpleEnumerator> dirList;
654 gDirectoryService->Get(NS_XPCOM_COMPONENT_DIR_LIST,
655 NS_GET_IID(nsISimpleEnumerator),
656 getter_AddRefs(dirList));
657 if (dirList) {
658 PRBool hasMore;
659 while (NS_SUCCEEDED(dirList->HasMoreElements(&hasMore)) && hasMore) {
660 nsCOMPtr<nsISupports> elem;
661 dirList->GetNext(getter_AddRefs(elem));
662 if (elem) {
663 nsCOMPtr<nsIFile> dir = do_QueryInterface(elem);
664 if (dir)
665 nsComponentManagerImpl::gComponentManager->AutoRegister(dir);
666
667 // XXX should we worry about new component loaders being
668 // XXX defined by this process?
669 }
670 }
671 }
672
673
674 // Make sure the compreg file's mod time is current.
675 nsCOMPtr<nsIFile> compregFile;
676 rv = gDirectoryService->Get(NS_XPCOM_COMPONENT_REGISTRY_FILE,
677 NS_GET_IID(nsIFile),
678 getter_AddRefs(compregFile));
679 RTTIMESPEC Time;
680 RTTimeNow(&Time);
681 compregFile->SetLastModifiedTime(RTTimeSpecGetMilli(&Time));
682 }
683
684 // Pay the cost at startup time of starting this singleton.
685 nsIInterfaceInfoManager* iim = XPTI_GetInterfaceInfoManager();
686 NS_IF_RELEASE(iim);
687#ifdef VBOX
688 // Must initialize the EventQueueService singleton before anyone is
689 // using it. The notification below creates a thread which races creating
690 // the EventQueueService creation otherwise, no matter what.
691 nsCOMPtr<nsIEventQueue> eventQ;
692 rv = NS_GetMainEventQ(getter_AddRefs(eventQ));
693 if (NS_FAILED(rv)) {
694 NS_ERROR("Could not create event queue for main thread");
695 /* this is just a build-time hack, to reference NS_ProxyRelease */
696 if (rv == 666)
697 NS_ProxyRelease(nsnull, nsnull);
698 return rv;
699 }
700#endif /* VBOX */
701
702 // Notify observers of xpcom autoregistration start
703 NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_OBSERVER_ID,
704 nsnull,
705 NS_XPCOM_STARTUP_OBSERVER_ID);
706
707#ifdef VBOX
708 gXPCOMInitialized = PR_TRUE;
709#endif
710 return NS_OK;
711}
712
713
714static nsVoidArray* gExitRoutines;
715
716static void CallExitRoutines()
717{
718 if (!gExitRoutines)
719 return;
720
721 PRInt32 count = gExitRoutines->Count();
722 for (PRInt32 i = 0; i < count; i++) {
723 XPCOMExitRoutine func = (XPCOMExitRoutine) gExitRoutines->ElementAt(i);
724 func();
725 }
726 gExitRoutines->Clear();
727 delete gExitRoutines;
728 gExitRoutines = nsnull;
729}
730
731nsresult NS_COM
732NS_RegisterXPCOMExitRoutine(XPCOMExitRoutine exitRoutine, PRUint32 priority)
733{
734 // priority are not used right now. It will need to be implemented as more
735 // classes are moved into the glue library --dougt
736 if (!gExitRoutines) {
737 gExitRoutines = new nsVoidArray();
738 if (!gExitRoutines) {
739 NS_WARNING("Failed to allocate gExitRoutines");
740 return NS_ERROR_FAILURE;
741 }
742 }
743
744 PRBool okay = gExitRoutines->AppendElement((void*)exitRoutine);
745 return okay ? NS_OK : NS_ERROR_FAILURE;
746}
747
748nsresult NS_COM
749NS_UnregisterXPCOMExitRoutine(XPCOMExitRoutine exitRoutine)
750{
751 if (!gExitRoutines)
752 return NS_ERROR_FAILURE;
753
754 PRBool okay = gExitRoutines->RemoveElement((void*)exitRoutine);
755 return okay ? NS_OK : NS_ERROR_FAILURE;
756}
757
758
759//
760// NS_ShutdownXPCOM()
761//
762// The shutdown sequence for xpcom would be
763//
764// - Release the Global Service Manager
765// - Release all service instances held by the global service manager
766// - Release the Global Service Manager itself
767// - Release the Component Manager
768// - Release all factories cached by the Component Manager
769// - Unload Libraries
770// - Release Contractid Cache held by Component Manager
771// - Release dll abstraction held by Component Manager
772// - Release the Registry held by Component Manager
773// - Finally, release the component manager itself
774//
775nsresult NS_COM NS_ShutdownXPCOM(nsIServiceManager* servMgr)
776{
777
778 // Notify observers of xpcom shutting down
779 nsresult rv = NS_OK;
780 {
781 // Block it so that the COMPtr will get deleted before we hit
782 // servicemanager shutdown
783 nsCOMPtr<nsIObserverService> observerService =
784 do_GetService("@mozilla.org/observer-service;1", &rv);
785 if (NS_SUCCEEDED(rv))
786 {
787 nsCOMPtr<nsIServiceManager> mgr;
788 rv = NS_GetServiceManager(getter_AddRefs(mgr));
789 if (NS_SUCCEEDED(rv))
790 {
791 (void) observerService->NotifyObservers(mgr,
792 NS_XPCOM_SHUTDOWN_OBSERVER_ID,
793 nsnull);
794 }
795 }
796 }
797
798 // grab the event queue so that we can process events one last time before exiting
799 nsCOMPtr <nsIEventQueue> currentQ;
800 {
801 nsCOMPtr<nsIEventQueueService> eventQService =
802 do_GetService(kEventQueueServiceCID, &rv);
803
804 if (eventQService) {
805 eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(currentQ));
806 }
807 }
808 // XPCOM is officially in shutdown mode NOW
809 // Set this only after the observers have been notified as this
810 // will cause servicemanager to become inaccessible.
811 gXPCOMShuttingDown = PR_TRUE;
812
813#ifdef DEBUG_dougt
814 fprintf(stderr, "* * * * XPCOM shutdown. Access will be denied * * * * \n");
815#endif
816
817#if 0 /// @todo later
818 IPC_Shutdown();
819#endif
820
821 // We may have AddRef'd for the caller of NS_InitXPCOM, so release it
822 // here again:
823 NS_IF_RELEASE(servMgr);
824
825 // Shutdown global servicemanager
826 if (nsComponentManagerImpl::gComponentManager) {
827 nsComponentManagerImpl::gComponentManager->FreeServices();
828 }
829 nsServiceManager::ShutdownGlobalServiceManager(nsnull);
830
831 if (currentQ) {
832 currentQ->ProcessPendingEvents();
833 currentQ = 0;
834 }
835
836 nsProxyObjectManager::Shutdown();
837
838 // Release the directory service
839 NS_IF_RELEASE(gDirectoryService);
840
841 // Shutdown nsLocalFile string conversion
842 NS_ShutdownLocalFile();
843#ifdef XP_UNIX
844 NS_ShutdownNativeCharsetUtils();
845#endif
846
847 CallExitRoutines();
848
849 // Shutdown xpcom. This will release all loaders and cause others holding
850 // a refcount to the component manager to release it.
851 if (nsComponentManagerImpl::gComponentManager) {
852 rv = (nsComponentManagerImpl::gComponentManager)->Shutdown();
853 NS_ASSERTION(NS_SUCCEEDED(rv), "Component Manager shutdown failed.");
854 } else
855 NS_WARNING("Component Manager was never created ...");
856
857 // Release our own singletons
858 // Do this _after_ shutting down the component manager, because the
859 // JS component loader will use XPConnect to call nsIModule::canUnload,
860 // and that will spin up the InterfaceInfoManager again -- bad mojo
861 XPTI_FreeInterfaceInfoManager();
862
863 // Finally, release the component manager last because it unloads the
864 // libraries:
865 if (nsComponentManagerImpl::gComponentManager) {
866 nsrefcnt cnt;
867 NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt);
868 NS_WARN_IF_FALSE(cnt == 0, "Component Manager being held past XPCOM shutdown.");
869 }
870 nsComponentManagerImpl::gComponentManager = nsnull;
871
872 ShutdownSpecialSystemDirectory();
873
874 EmptyEnumeratorImpl::Shutdown();
875
876 NS_PurgeAtomTable();
877
878 NS_IF_RELEASE(gDebug);
879
880#ifdef NS_BUILD_REFCNT_LOGGING
881 nsTraceRefcntImpl::DumpStatistics();
882 nsTraceRefcntImpl::ResetStatistics();
883 nsTraceRefcntImpl::Shutdown();
884#endif
885
886#ifdef VBOX
887 gXPCOMInitialized = PR_FALSE;
888#endif
889 return NS_OK;
890}
891
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette