~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/xpcom/build/nsXPComInit.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
4
 *
 
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/
 
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 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.
 
35
 *
 
36
 * ***** END LICENSE BLOCK ***** */
 
37
 
 
38
#include "nsXPCOM.h"
 
39
#include "nsXPCOMPrivate.h"
 
40
#include "nscore.h"
 
41
#include "prlink.h"
 
42
#include "nsCOMPtr.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"
 
51
 
 
52
#include "nsMemoryImpl.h"
 
53
#include "nsDebugImpl.h"
 
54
#include "nsTraceRefcntImpl.h"
 
55
#include "nsErrorService.h"
 
56
#include "nsByteBuffer.h"
 
57
 
 
58
#include "nsSupportsArray.h"
 
59
#include "nsArray.h"
 
60
#include "nsSupportsPrimitives.h"
 
61
#include "nsConsoleService.h"
 
62
#include "nsExceptionService.h"
 
63
 
 
64
#include "nsComponentManager.h"
 
65
#include "nsCategoryManagerUtils.h"
 
66
#include "nsIServiceManager.h"
 
67
#include "nsGenericFactory.h"
 
68
 
 
69
#include "nsEventQueueService.h"
 
70
#include "nsEventQueue.h"
 
71
 
 
72
#include "nsIProxyObjectManager.h"
 
73
#include "nsProxyEventPrivate.h"  // access to the impl of nsProxyObjectManager for the generic factory registration.
 
74
 
 
75
#include "xptinfo.h"
 
76
#include "nsIInterfaceInfoManager.h"
 
77
 
 
78
#include "nsTimerImpl.h"
 
79
#include "TimerThread.h"
 
80
 
 
81
#include "nsThread.h"
 
82
#include "nsProcess.h"
 
83
#include "nsEnvironment.h"
 
84
 
 
85
#include "nsEmptyEnumerator.h"
 
86
 
 
87
#include "nsILocalFile.h"
 
88
#include "nsLocalFile.h"
 
89
#if defined(XP_UNIX) || defined(XP_OS2)
 
90
#include "nsNativeCharsetUtils.h"
 
91
#endif
 
92
#include "nsDirectoryService.h"
 
93
#include "nsDirectoryServiceDefs.h"
 
94
#include "nsCategoryManager.h"
 
95
#include "nsICategoryManager.h"
 
96
#include "nsStringStream.h"
 
97
#include "nsMultiplexInputStream.h"
 
98
 
 
99
#include "nsFastLoadService.h"
 
100
 
 
101
#include "nsAtomService.h"
 
102
#include "nsAtomTable.h"
 
103
#include "nsTraceRefcnt.h"
 
104
#include "nsTimelineService.h"
 
105
 
 
106
#include "nsVariant.h"
 
107
 
 
108
#ifdef GC_LEAK_DETECTOR
 
109
#include "nsLeakDetector.h"
 
110
#endif
 
111
#include "nsRecyclingAllocator.h"
 
112
 
 
113
#include "SpecialSystemDirectory.h"
 
114
 
 
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** );
 
122
 
 
123
#ifdef DEBUG
 
124
extern void _FreeAutoLockStatics();
 
125
#endif
 
126
 
 
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);
 
130
 
 
131
NS_GENERIC_FACTORY_CONSTRUCTOR(nsProcess)
 
132
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsEventQueueServiceImpl, Init)
 
133
 
 
134
#define NS_ENVIRONMENT_CLASSNAME "Environment Service"
 
135
 
 
136
#include "nsXPCOM.h"
 
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"
 
155
 
 
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)
 
173
 
 
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)
 
183
 
 
184
NS_GENERIC_FACTORY_CONSTRUCTOR(nsVariant)
 
185
 
 
186
NS_GENERIC_FACTORY_CONSTRUCTOR(nsRecyclingAllocatorImpl)
 
187
 
 
188
#ifdef MOZ_TIMELINE
 
189
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimelineService)
 
190
#endif
 
191
 
 
192
static NS_METHOD
 
193
nsXPTIInterfaceInfoManagerGetSingleton(nsISupports* outer,
 
194
                                       const nsIID& aIID,
 
195
                                       void* *aInstancePtr)
 
196
{
 
197
    NS_ENSURE_ARG_POINTER(aInstancePtr);
 
198
    NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION);
 
199
 
 
200
    nsCOMPtr<nsIInterfaceInfoManager> iim(dont_AddRef(XPTI_GetInterfaceInfoManager()));
 
201
    if (!iim) {
 
202
        return NS_ERROR_FAILURE;
 
203
    }
 
204
 
 
205
    return iim->QueryInterface(aIID, aInstancePtr);
 
206
}
 
207
 
 
208
 
 
209
PR_STATIC_CALLBACK(nsresult)
 
210
RegisterGenericFactory(nsIComponentRegistrar* registrar,
 
211
                       const nsModuleComponentInfo *info)
 
212
{
 
213
    nsresult rv;
 
214
    nsIGenericFactory* fact;
 
215
    rv = NS_NewGenericFactory(&fact, info);
 
216
    if (NS_FAILED(rv)) return rv;
 
217
 
 
218
    rv = registrar->RegisterFactory(info->mCID, 
 
219
                                    info->mDescription,
 
220
                                    info->mContractID, 
 
221
                                    fact);
 
222
    NS_RELEASE(fact);
 
223
    return rv;
 
224
}
 
225
 
 
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()
 
232
{
 
233
    nsresult rv;
 
234
    nsCOMPtr<nsIProperties> directoryService;
 
235
    nsDirectoryService::Create(nsnull, 
 
236
                               NS_GET_IID(nsIProperties), 
 
237
                               getter_AddRefs(directoryService));  
 
238
    
 
239
    if (!directoryService) 
 
240
        return PR_FALSE;
 
241
 
 
242
    nsCOMPtr<nsIFile> file;
 
243
    rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, 
 
244
                               NS_GET_IID(nsIFile), 
 
245
                               getter_AddRefs(file));
 
246
 
 
247
    if (NS_FAILED(rv)) {
 
248
        NS_WARNING("Getting NS_XPCOM_CURRENT_PROCESS_DIR failed");
 
249
        return PR_FALSE;
 
250
    }
 
251
 
 
252
    file->AppendNative(nsDependentCString(".autoreg"));
 
253
    
 
254
    PRBool exists;
 
255
    file->Exists(&exists);
 
256
    if (!exists)
 
257
        return PR_FALSE;
 
258
 
 
259
    nsCOMPtr<nsIFile> compregFile;
 
260
    rv = directoryService->Get(NS_XPCOM_COMPONENT_REGISTRY_FILE,
 
261
                               NS_GET_IID(nsIFile),
 
262
                               getter_AddRefs(compregFile));
 
263
 
 
264
    
 
265
    if (NS_FAILED(rv)) {
 
266
        NS_WARNING("Getting NS_XPCOM_COMPONENT_REGISTRY_FILE failed");
 
267
        return PR_FALSE;
 
268
    }
 
269
 
 
270
    // Don't need to check whether compreg exists; if it doesn't
 
271
    // we won't even be here.
 
272
 
 
273
    PRInt64 compregModTime, autoregModTime;
 
274
    compregFile->GetLastModifiedTime(&compregModTime);
 
275
    file->GetLastModifiedTime(&autoregModTime);
 
276
 
 
277
    return LL_CMP(autoregModTime, >, compregModTime);
 
278
}
 
279
 
 
280
 
 
281
nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = NULL;
 
282
nsIProperties     *gDirectoryService = NULL;
 
283
PRBool gXPCOMShuttingDown = PR_FALSE;
 
284
 
 
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;
 
290
 
 
291
// For each class that wishes to support nsIClassInfo, add a line like this
 
292
// NS_DECL_CLASSINFO(nsMyClass)
 
293
 
 
294
#define COMPONENT(NAME, Ctor)                                                  \
 
295
 { NS_##NAME##_CLASSNAME, NS_##NAME##_CID, NS_##NAME##_CONTRACTID, Ctor }
 
296
 
 
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) }
 
301
 
 
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),
 
307
 
 
308
    COMPONENT(BYTEBUFFER, ByteBufferImpl::Create),
 
309
    COMPONENT(SCRIPTABLEINPUTSTREAM, nsScriptableInputStream::Create),
 
310
    COMPONENT(BINARYINPUTSTREAM, nsBinaryInputStreamConstructor),
 
311
    COMPONENT(BINARYOUTPUTSTREAM, nsBinaryOutputStreamConstructor),
 
312
    COMPONENT(STORAGESTREAM, nsStorageStreamConstructor),
 
313
 
 
314
#define NS_PROPERTIES_CLASSNAME  "Properties"
 
315
    COMPONENT(PROPERTIES, nsProperties::Create),
 
316
 
 
317
#define NS_PERSISTENTPROPERTIES_CID NS_IPERSISTENTPROPERTIES_CID /* sigh */
 
318
    COMPONENT(PERSISTENTPROPERTIES, nsPersistentProperties::Create),
 
319
 
 
320
    COMPONENT(SUPPORTSARRAY, nsSupportsArray::Create),
 
321
    COMPONENT(ARRAY, nsArrayConstructor),
 
322
    COMPONENT(CONSOLESERVICE, nsConsoleServiceConstructor),
 
323
    COMPONENT(EXCEPTIONSERVICE, nsExceptionServiceConstructor),
 
324
    COMPONENT(ATOMSERVICE, nsAtomServiceConstructor),
 
325
#ifdef MOZ_TIMELINE
 
326
    COMPONENT(TIMELINESERVICE, nsTimelineServiceConstructor),
 
327
#endif
 
328
    COMPONENT(OBSERVERSERVICE, nsObserverService::Create),
 
329
    COMPONENT(GENERICFACTORY, nsGenericFactory::Create),
 
330
    COMPONENT(EVENTQUEUESERVICE, nsEventQueueServiceImplConstructor),
 
331
    COMPONENT(EVENTQUEUE, nsEventQueueImpl::Create),
 
332
    COMPONENT(THREAD, nsThread::Create),
 
333
 
 
334
#define NS_XPCOMPROXY_CID NS_PROXYEVENT_MANAGER_CID
 
335
    COMPONENT(XPCOMPROXY, nsProxyObjectManager::Create),
 
336
 
 
337
    COMPONENT(TIMER, nsTimerImplConstructor),
 
338
    COMPONENT(TIMERMANAGER, nsTimerManagerConstructor),
 
339
 
 
340
#define COMPONENT_SUPPORTS(TYPE, Type)                                         \
 
341
  COMPONENT(SUPPORTS_##TYPE, nsSupports##Type##ImplConstructor)
 
342
 
 
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),
 
360
 
 
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),
 
368
 
 
369
    COMPONENT(STRINGINPUTSTREAM, nsStringInputStreamConstructor),
 
370
    COMPONENT(MULTIPLEXINPUTSTREAM, nsMultiplexInputStreamConstructor),
 
371
 
 
372
    COMPONENT(FASTLOADSERVICE, nsFastLoadService::Create),
 
373
    COMPONENT(VARIANT, nsVariantConstructor),
 
374
    COMPONENT(INTERFACEINFOMANAGER_SERVICE, nsXPTIInterfaceInfoManagerGetSingleton),
 
375
 
 
376
    COMPONENT(RECYCLINGALLOCATOR, nsRecyclingAllocatorImplConstructor),
 
377
};
 
378
 
 
379
#undef COMPONENT
 
380
 
 
381
const int components_length = sizeof(components) / sizeof(components[0]);
 
382
 
 
383
// gMemory will be freed during shutdown.
 
384
static nsIMemory* gMemory = nsnull;
 
385
nsresult NS_COM NS_GetMemoryManager(nsIMemory* *result)
 
386
{
 
387
    nsresult rv = NS_OK;
 
388
    if (!gMemory)
 
389
    {
 
390
        rv = nsMemoryImpl::Create(nsnull,
 
391
                                  NS_GET_IID(nsIMemory),
 
392
                                  (void**)&gMemory);
 
393
    }
 
394
    NS_IF_ADDREF(*result = gMemory);
 
395
    return rv;
 
396
}
 
397
 
 
398
// gDebug will be freed during shutdown.
 
399
static nsIDebug* gDebug = nsnull;
 
400
nsresult NS_COM NS_GetDebug(nsIDebug** result)
 
401
{
 
402
    nsresult rv = NS_OK;
 
403
    if (!gDebug)
 
404
    {
 
405
        rv = nsDebugImpl::Create(nsnull, 
 
406
                                 NS_GET_IID(nsIDebug), 
 
407
                                 (void**)&gDebug);
 
408
    }
 
409
    NS_IF_ADDREF(*result = gDebug);
 
410
    return rv;
 
411
}
 
412
 
 
413
#ifdef NS_BUILD_REFCNT_LOGGING
 
414
// gTraceRefcnt will be freed during shutdown.
 
415
static nsITraceRefcnt* gTraceRefcnt = nsnull;
 
416
#endif
 
417
 
 
418
nsresult NS_COM NS_GetTraceRefcnt(nsITraceRefcnt** result)
 
419
{
 
420
#ifdef NS_BUILD_REFCNT_LOGGING
 
421
    nsresult rv = NS_OK;
 
422
    if (!gTraceRefcnt)
 
423
    {
 
424
        rv = nsTraceRefcntImpl::Create(nsnull, 
 
425
                                       NS_GET_IID(nsITraceRefcnt), 
 
426
                                       (void**)&gTraceRefcnt);
 
427
    }
 
428
    NS_IF_ADDREF(*result = gTraceRefcnt);
 
429
    return rv;
 
430
#else
 
431
    return NS_ERROR_NOT_INITIALIZED;
 
432
#endif
 
433
}
 
434
 
 
435
nsresult NS_COM NS_InitXPCOM(nsIServiceManager* *result,
 
436
                             nsIFile* binDirectory)
 
437
{
 
438
    return NS_InitXPCOM2(result, binDirectory, nsnull);
 
439
}
 
440
 
 
441
nsresult NS_COM NS_InitXPCOM2(nsIServiceManager* *result,
 
442
                              nsIFile* binDirectory,
 
443
                              nsIDirectoryServiceProvider* appFileLocationProvider)
 
444
{
 
445
 
 
446
    if (!gXPCOMHasGlobalsBeenInitalized)
 
447
        return NS_ERROR_NOT_INITIALIZED;
 
448
 
 
449
    nsresult rv = NS_OK;
 
450
 
 
451
     // We are not shutting down
 
452
    gXPCOMShuttingDown = PR_FALSE;
 
453
 
 
454
#ifdef NS_BUILD_REFCNT_LOGGING
 
455
    nsTraceRefcntImpl::Startup();
 
456
#endif
 
457
 
 
458
    // Establish the main thread here.
 
459
    rv = nsIThread::SetMainThread();
 
460
    if (NS_FAILED(rv)) return rv;
 
461
 
 
462
    // Startup the memory manager
 
463
    rv = nsMemoryImpl::Startup();
 
464
    if (NS_FAILED(rv)) return rv;
 
465
 
 
466
#if defined(XP_UNIX) || defined(XP_OS2)
 
467
    NS_StartupNativeCharsetUtils();
 
468
#endif
 
469
    NS_StartupLocalFile();
 
470
 
 
471
    StartupSpecialSystemDirectory();
 
472
 
 
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);
 
477
    if (NS_FAILED(rv))
 
478
        return rv;
 
479
 
 
480
    nsCOMPtr<nsIDirectoryService> dirService = do_QueryInterface(gDirectoryService, &rv);
 
481
    if (NS_FAILED(rv))
 
482
        return rv;
 
483
    rv = dirService->Init();
 
484
    if (NS_FAILED(rv))
 
485
        return rv;
 
486
 
 
487
    // Create the Component/Service Manager
 
488
    nsComponentManagerImpl *compMgr = NULL;
 
489
 
 
490
    if (nsComponentManagerImpl::gComponentManager == NULL)
 
491
    {
 
492
        compMgr = new nsComponentManagerImpl();
 
493
        if (compMgr == NULL)
 
494
            return NS_ERROR_OUT_OF_MEMORY;
 
495
        NS_ADDREF(compMgr);
 
496
        
 
497
        nsCOMPtr<nsIFile> xpcomLib;
 
498
                
 
499
        PRBool value;
 
500
        if (binDirectory)
 
501
        {
 
502
            rv = binDirectory->IsDirectory(&value);
 
503
 
 
504
            if (NS_SUCCEEDED(rv) && value) {
 
505
                gDirectoryService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, binDirectory);
 
506
                binDirectory->Clone(getter_AddRefs(xpcomLib));
 
507
            }
 
508
        }
 
509
        else {
 
510
            gDirectoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, 
 
511
                                   NS_GET_IID(nsIFile), 
 
512
                                   getter_AddRefs(xpcomLib));
 
513
        }
 
514
 
 
515
        if (xpcomLib) {
 
516
            xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL));
 
517
            gDirectoryService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);
 
518
        }
 
519
        
 
520
        if (appFileLocationProvider) {
 
521
            rv = dirService->RegisterProvider(appFileLocationProvider);
 
522
            if (NS_FAILED(rv)) return rv;
 
523
        }
 
524
 
 
525
        rv = compMgr->Init();
 
526
        if (NS_FAILED(rv))
 
527
        {
 
528
            NS_RELEASE(compMgr);
 
529
            return rv;
 
530
        }
 
531
 
 
532
        nsComponentManagerImpl::gComponentManager = compMgr;
 
533
 
 
534
        if (result) {
 
535
            nsIServiceManager *serviceManager =
 
536
                NS_STATIC_CAST(nsIServiceManager*, compMgr);
 
537
 
 
538
            NS_ADDREF(*result = serviceManager);
 
539
        }
 
540
    }
 
541
 
 
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;
 
547
 
 
548
    rv = compMgr->RegisterService(kComponentManagerCID, NS_STATIC_CAST(nsIComponentManager*, compMgr));
 
549
    if (NS_FAILED(rv)) return rv;
 
550
 
 
551
#ifdef GC_LEAK_DETECTOR
 
552
  rv = NS_InitLeakDetector();
 
553
    if (NS_FAILED(rv)) return rv;
 
554
#endif
 
555
 
 
556
    // 2. Register the global services with the component manager so that
 
557
    //    clients can create new objects.
 
558
 
 
559
    // Category Manager
 
560
    {
 
561
      nsCOMPtr<nsIFactory> categoryManagerFactory;
 
562
      if ( NS_FAILED(rv = NS_CategoryManagerGetFactory(getter_AddRefs(categoryManagerFactory))) )
 
563
        return rv;
 
564
 
 
565
      NS_DEFINE_CID(kCategoryManagerCID, NS_CATEGORYMANAGER_CID);
 
566
 
 
567
      rv = compMgr->RegisterFactory(kCategoryManagerCID,
 
568
                                    NS_CATEGORYMANAGER_CLASSNAME,
 
569
                                    NS_CATEGORYMANAGER_CONTRACTID,
 
570
                                    categoryManagerFactory,
 
571
                                    PR_TRUE);
 
572
      if ( NS_FAILED(rv) ) return rv;
 
573
    }
 
574
 
 
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);
 
579
    if (registrar) {
 
580
        for (int i = 0; i < components_length; i++)
 
581
            RegisterGenericFactory(registrar, &components[i]);
 
582
    }
 
583
    rv = nsComponentManagerImpl::gComponentManager->ReadPersistentRegistry();
 
584
#ifdef DEBUG    
 
585
    if (NS_FAILED(rv)) {
 
586
        printf("No Persistent Registry Found.\n");        
 
587
    }
 
588
#endif
 
589
 
 
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);
 
594
 
 
595
        // If the application is using a GRE, then, 
 
596
        // auto register components in the GRE directory as well.
 
597
        //
 
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
 
601
        //
 
602
 
 
603
        if ( appFileLocationProvider ) {
 
604
            nsCOMPtr<nsIFile> greDir;
 
605
            PRBool persistent = PR_TRUE;
 
606
 
 
607
            appFileLocationProvider->GetFile(NS_GRE_DIR, &persistent, getter_AddRefs(greDir));
 
608
 
 
609
            if (greDir) {
 
610
#ifdef DEBUG_dougt
 
611
                printf("start - Registering GRE components\n");
 
612
#endif
 
613
                rv = gDirectoryService->Get(NS_GRE_COMPONENT_DIR,
 
614
                                            NS_GET_IID(nsIFile),
 
615
                                            getter_AddRefs(greDir));
 
616
                if (NS_FAILED(rv)) {
 
617
                    NS_ERROR("Could not get GRE components directory!");
 
618
                    return rv;
 
619
                }
 
620
 
 
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);
 
625
                
 
626
                if (loaderCount != nsComponentManagerImpl::gComponentManager->GetLoaderCount()) 
 
627
                    nsComponentManagerImpl::gComponentManager->AutoRegisterNonNativeComponents(nsnull);        
 
628
 
 
629
#ifdef DEBUG_dougt
 
630
                printf("end - Registering GRE components\n");
 
631
#endif          
 
632
                if (NS_FAILED(rv)) {
 
633
                    NS_ERROR("Could not AutoRegister GRE components");
 
634
                    return rv;
 
635
                }
 
636
            }
 
637
        }
 
638
 
 
639
        //
 
640
        // If additional component directories have been specified, then
 
641
        // register them as well.
 
642
        //
 
643
 
 
644
        nsCOMPtr<nsISimpleEnumerator> dirList;
 
645
        gDirectoryService->Get(NS_XPCOM_COMPONENT_DIR_LIST,
 
646
                               NS_GET_IID(nsISimpleEnumerator),
 
647
                               getter_AddRefs(dirList));
 
648
        if (dirList) {
 
649
            PRBool hasMore;
 
650
            while (NS_SUCCEEDED(dirList->HasMoreElements(&hasMore)) && hasMore) {
 
651
                nsCOMPtr<nsISupports> elem;
 
652
                dirList->GetNext(getter_AddRefs(elem));
 
653
                if (elem) {
 
654
                    nsCOMPtr<nsIFile> dir = do_QueryInterface(elem);
 
655
                    if (dir)
 
656
                        nsComponentManagerImpl::gComponentManager->AutoRegister(dir);
 
657
 
 
658
                    // XXX should we worry about new component loaders being
 
659
                    // XXX defined by this process?
 
660
                }
 
661
            }
 
662
        }
 
663
 
 
664
 
 
665
        // Make sure the compreg file's mod time is current.
 
666
        nsCOMPtr<nsIFile> compregFile;
 
667
        rv = gDirectoryService->Get(NS_XPCOM_COMPONENT_REGISTRY_FILE,
 
668
                                    NS_GET_IID(nsIFile),
 
669
                                    getter_AddRefs(compregFile));
 
670
        compregFile->SetLastModifiedTime(PR_Now() / 1000);
 
671
    }
 
672
    
 
673
    // Pay the cost at startup time of starting this singleton.
 
674
    nsIInterfaceInfoManager* iim = XPTI_GetInterfaceInfoManager();
 
675
    NS_IF_RELEASE(iim);
 
676
 
 
677
    // Notify observers of xpcom autoregistration start
 
678
    NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_OBSERVER_ID, 
 
679
                                  nsnull,
 
680
                                  NS_XPCOM_STARTUP_OBSERVER_ID);
 
681
    
 
682
    return NS_OK;
 
683
}
 
684
 
 
685
 
 
686
static nsVoidArray* gExitRoutines;
 
687
 
 
688
static void CallExitRoutines()
 
689
{
 
690
    if (!gExitRoutines)
 
691
        return;
 
692
 
 
693
    PRInt32 count = gExitRoutines->Count();
 
694
    for (PRInt32 i = 0; i < count; i++) {
 
695
        XPCOMExitRoutine func = (XPCOMExitRoutine) gExitRoutines->ElementAt(i);
 
696
        func();
 
697
    }
 
698
    gExitRoutines->Clear();
 
699
    delete gExitRoutines;
 
700
    gExitRoutines = nsnull;
 
701
}
 
702
 
 
703
nsresult NS_COM
 
704
NS_RegisterXPCOMExitRoutine(XPCOMExitRoutine exitRoutine, PRUint32 priority)
 
705
{
 
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;
 
713
        }
 
714
    }
 
715
 
 
716
    PRBool okay = gExitRoutines->AppendElement((void*)exitRoutine);
 
717
    return okay ? NS_OK : NS_ERROR_FAILURE;
 
718
}
 
719
 
 
720
nsresult NS_COM
 
721
NS_UnregisterXPCOMExitRoutine(XPCOMExitRoutine exitRoutine)
 
722
{
 
723
    if (!gExitRoutines)
 
724
        return NS_ERROR_FAILURE;
 
725
 
 
726
    PRBool okay = gExitRoutines->RemoveElement((void*)exitRoutine);
 
727
    return okay ? NS_OK : NS_ERROR_FAILURE;
 
728
}
 
729
 
 
730
 
 
731
//
 
732
// NS_ShutdownXPCOM()
 
733
//
 
734
// The shutdown sequence for xpcom would be
 
735
//
 
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
 
746
//
 
747
nsresult NS_COM NS_ShutdownXPCOM(nsIServiceManager* servMgr)
 
748
{
 
749
 
 
750
    // Notify observers of xpcom shutting down
 
751
    nsresult rv = NS_OK;
 
752
    {
 
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))
 
758
        {
 
759
            nsCOMPtr<nsIServiceManager> mgr;
 
760
            rv = NS_GetServiceManager(getter_AddRefs(mgr));
 
761
            if (NS_SUCCEEDED(rv))
 
762
            {
 
763
                (void) observerService->NotifyObservers(mgr,
 
764
                                                        NS_XPCOM_SHUTDOWN_OBSERVER_ID,
 
765
                                                        nsnull);
 
766
            }
 
767
        }
 
768
    }
 
769
 
 
770
    // grab the event queue so that we can process events one last time before exiting
 
771
    nsCOMPtr <nsIEventQueue> currentQ;
 
772
    {
 
773
        nsCOMPtr<nsIEventQueueService> eventQService =
 
774
                 do_GetService(kEventQueueServiceCID, &rv);
 
775
 
 
776
        if (eventQService) {
 
777
            eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(currentQ));
 
778
        }
 
779
    }
 
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;
 
784
 
 
785
#ifdef DEBUG_dougt
 
786
    fprintf(stderr, "* * * * XPCOM shutdown. Access will be denied * * * * \n");
 
787
#endif
 
788
    // We may have AddRef'd for the caller of NS_InitXPCOM, so release it
 
789
    // here again:
 
790
    NS_IF_RELEASE(servMgr);
 
791
 
 
792
    // Shutdown global servicemanager
 
793
    if (nsComponentManagerImpl::gComponentManager) {
 
794
        nsComponentManagerImpl::gComponentManager->FreeServices();
 
795
    }
 
796
    nsServiceManager::ShutdownGlobalServiceManager(nsnull);
 
797
 
 
798
    if (currentQ) {
 
799
        currentQ->ProcessPendingEvents();
 
800
        currentQ = 0;
 
801
    }
 
802
    
 
803
    nsProxyObjectManager::Shutdown();
 
804
 
 
805
    // Release the directory service
 
806
    NS_IF_RELEASE(gDirectoryService);
 
807
 
 
808
    // Shutdown nsLocalFile string conversion
 
809
    NS_ShutdownLocalFile();
 
810
#ifdef XP_UNIX
 
811
    NS_ShutdownNativeCharsetUtils();
 
812
#endif
 
813
 
 
814
    // Shutdown the timer thread and all timers that might still be alive before
 
815
    // shutting down the component manager
 
816
    nsTimerImpl::Shutdown();
 
817
 
 
818
    CallExitRoutines();
 
819
 
 
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.");
 
825
    } else
 
826
        NS_WARNING("Component Manager was never created ...");
 
827
 
 
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();
 
833
 
 
834
    // Finally, release the component manager last because it unloads the
 
835
    // libraries:
 
836
    if (nsComponentManagerImpl::gComponentManager) {
 
837
      nsrefcnt cnt;
 
838
      NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt);
 
839
      NS_WARN_IF_FALSE(cnt == 0, "Component Manager being held past XPCOM shutdown.");
 
840
    }
 
841
    nsComponentManagerImpl::gComponentManager = nsnull;
 
842
 
 
843
#ifdef DEBUG
 
844
    _FreeAutoLockStatics();
 
845
#endif
 
846
 
 
847
    ShutdownSpecialSystemDirectory();
 
848
 
 
849
    EmptyEnumeratorImpl::Shutdown();
 
850
    nsMemoryImpl::Shutdown();
 
851
    NS_IF_RELEASE(gMemory);
 
852
 
 
853
    nsThread::Shutdown();
 
854
    NS_PurgeAtomTable();
 
855
 
 
856
    NS_IF_RELEASE(gDebug);
 
857
 
 
858
#ifdef NS_BUILD_REFCNT_LOGGING
 
859
    nsTraceRefcntImpl::DumpStatistics();
 
860
    nsTraceRefcntImpl::ResetStatistics();
 
861
    nsTraceRefcntImpl::Shutdown();
 
862
#endif
 
863
 
 
864
#ifdef GC_LEAK_DETECTOR
 
865
    // Shutdown the Leak detector.
 
866
    NS_ShutdownLeakDetector();
 
867
#endif
 
868
 
 
869
    gXPCOMHasGlobalsBeenInitalized = PR_FALSE;
 
870
    return NS_OK;
 
871
}
 
872
 
 
873
#define GET_FUNC(_tag, _decl, _name)                        \
 
874
  functions->_tag = (_decl) PR_FindSymbol(xpcomLib, _name); \
 
875
  if (!functions->_tag) goto end
 
876
 
 
877
nsresult NS_COM PR_CALLBACK
 
878
NS_GetFrozenFunctions(XPCOMFunctions *functions, const char* libraryPath)
 
879
{
 
880
    if (!functions)
 
881
        return NS_ERROR_OUT_OF_MEMORY;
 
882
 
 
883
    if (functions->version != XPCOM_GLUE_VERSION)
 
884
        return NS_ERROR_FAILURE;
 
885
 
 
886
    PRLibrary *xpcomLib = PR_LoadLibrary(libraryPath);
 
887
    if (!xpcomLib)
 
888
        return NS_ERROR_FAILURE;
 
889
 
 
890
    nsresult rv = NS_ERROR_FAILURE;
 
891
 
 
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");
 
902
 
 
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");
 
907
    }
 
908
 
 
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");
 
927
    }
 
928
 
 
929
    rv = NS_OK;
 
930
end:
 
931
    PR_UnloadLibrary(xpcomLib); // the library is refcnt'ed above by the caller.
 
932
    return rv;
 
933
}