From 6896473ecef8deeb8309469c2b16cbd60737c885 Mon Sep 17 00:00:00 2001 From: "shaver%netscape.com" Date: Wed, 10 Nov 1999 00:28:34 +0000 Subject: [PATCH] - NS_ERROR_FACTORY_REGISTER_AGAIN for deferring registration of a module until later in the autoreg cycle. - teach native component loader about deferred components - add nsIComponentLoader::registerDeferredComponents - teach component manager about deferred components - made nsID::Parse take a |const char *| instead of a simple |char *|. - move release of XPTI singletons until _after_ shutting down the component manager to prevent re-initialization during JS component shutdown. - category manager work: really delete from reg, start on enumeration - use nsXPIDLCString instead of autoStringFree. - fix nsRegistry to use allocator properly. - cleaner memory management in nsFactoryEntry. - capitalization fixed in nsIComponentLoader.idl - clean up loader creation logic - remove/disable lots of DEBUG_shaver noise - added (disabled) warning about NSGetFactory usage - move .so and .shlb higher up in the ValidDllExtensions list to marginally speed up registration. - added nsDll::GetRegistryLocation API - properly export nsSupportsArray.h - capitalization fixes in nsIEnumerator.idl - added deferral to nsSample.js git-svn-id: svn://10.0.0.236/trunk@53047 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/modules/libreg/xpcom/nsRegistry.cpp | 30 +-- mozilla/xpcom/base/nsError.h | 3 + mozilla/xpcom/base/nsID.cpp | 2 +- mozilla/xpcom/base/nsID.h | 2 +- mozilla/xpcom/build/nsXPComInit.cpp | 6 + mozilla/xpcom/components/nsCategoryManager.js | 36 +++- .../xpcom/components/nsComponentManager.cpp | 183 ++++++++---------- mozilla/xpcom/components/nsComponentManager.h | 9 +- .../xpcom/components/nsIComponentLoader.idl | 19 +- .../components/nsNativeComponentLoader.cpp | 152 +++++++-------- .../components/nsNativeComponentLoader.h | 5 +- mozilla/xpcom/components/nsRegistry.cpp | 30 +-- mozilla/xpcom/components/xcDll.h | 2 + mozilla/xpcom/ds/MANIFEST | 1 + mozilla/xpcom/ds/Makefile.in | 1 + mozilla/xpcom/ds/makefile.win | 1 + mozilla/xpcom/ds/nsIEnumerator.idl | 8 +- mozilla/xpcom/glue/nsID.cpp | 2 +- mozilla/xpcom/glue/nsID.h | 2 +- mozilla/xpcom/sample/nsSample.js | 24 +++ mozilla/xpcom/tools/registry/regExport.cpp | 3 +- 21 files changed, 266 insertions(+), 255 deletions(-) diff --git a/mozilla/modules/libreg/xpcom/nsRegistry.cpp b/mozilla/modules/libreg/xpcom/nsRegistry.cpp index 2000b2ebd3d..c764dc36d2b 100644 --- a/mozilla/modules/libreg/xpcom/nsRegistry.cpp +++ b/mozilla/modules/libreg/xpcom/nsRegistry.cpp @@ -27,6 +27,8 @@ #include "prmem.h" #include "prlock.h" #include "prlog.h" +#include "nsCRT.h" +#include "nsAllocator.h" /* extra locking for the paranoid */ /* #define EXTRA_THREADSAFE */ @@ -306,18 +308,6 @@ static void reginfo2Length( const REGINFO &in, PRUint32 &out ) { } } -/*-------------------------------- PR_strdup ----------------------------------- -| Utility function that does PR_Malloc and copies argument string. Caller | -| must do PR_Free. | -------------------------------------------------------------------------------*/ -static char *PR_strdup( const char *in ) { - char *result = (char*)PR_Malloc( strlen( in ) + 1 ); - if ( result ) { - strcpy( result, in ); - } - return result; -} - /*------------------------ nsISupports Implementation -------------------------- | This code generates the implementation of the nsISupports member functions | | for each class implemented in this file. | @@ -525,12 +515,8 @@ NS_IMETHODIMP nsRegistry::GetString( nsRegistryKey baseKey, const char *path, ch if ( err == REGERR_OK ) { - // Allocate buffer for return value - PRUint32 vallen = PL_strlen(regStr); - *result = (char*)PR_Malloc( vallen + 1 ); - if (*result) - PL_strcpy(*result, regStr); - else + *result = nsCRT::strdup(regStr); + if (!*result) rv = NS_ERROR_OUT_OF_MEMORY; } else if ( err == REGERR_BUFTOOSMALL ) @@ -541,7 +527,7 @@ NS_IMETHODIMP nsRegistry::GetString( nsRegistryKey baseKey, const char *path, ch // See if that worked. if( rv == NS_OK ) { - *result =(char*)PR_Malloc( length + 1 ); + *result =(char*)nsAllocator::Alloc( length + 1 ); if( *result ) { // Get string from registry into result buffer. @@ -554,7 +540,7 @@ NS_IMETHODIMP nsRegistry::GetString( nsRegistryKey baseKey, const char *path, ch if ( rv != NS_OK ) { // Didn't get result, free buffer - PR_Free( *result ); + nsCRT::free( *result ); *result = 0; } } @@ -1173,7 +1159,7 @@ nsRegistryNode::~nsRegistryNode() NS_IMETHODIMP nsRegistryNode::GetName( char **result ) { if (result == NULL) return NS_ERROR_NULL_POINTER; // Make sure there is a place to put the result. - *result = PR_strdup( mName ); + *result = nsCRT::strdup( mName ); if ( !*result ) return NS_ERROR_OUT_OF_MEMORY; return NS_OK; } @@ -1223,7 +1209,7 @@ NS_IMETHODIMP nsRegistryValue::GetName( char **result ) { rv = getInfo(); if( rv == NS_OK || rv == NS_ERROR_REG_NO_MORE ) { // worked, return actual result. - *result = PR_strdup( mName ); + *result = nsCRT::strdup( mName ); if ( *result ) { rv = NS_OK; } else { diff --git a/mozilla/xpcom/base/nsError.h b/mozilla/xpcom/base/nsError.h index ce61102feee..d9557c21139 100644 --- a/mozilla/xpcom/base/nsError.h +++ b/mozilla/xpcom/base/nsError.h @@ -172,6 +172,9 @@ typedef PRUint32 nsresult; /* Returned when a class is not registered */ #define NS_ERROR_FACTORY_NOT_REGISTERED ((nsresult) 0x80040154L) +/* Returned when a class cannot be registered, but may be tried again later */ +#define NS_ERROR_FACTORY_REGISTER_AGAIN ((nsresult) 0x80040155L) + /* Returned when a dynamically loaded factory couldn't be found */ #define NS_ERROR_FACTORY_NOT_LOADED ((nsresult) 0x800401f8L) diff --git a/mozilla/xpcom/base/nsID.cpp b/mozilla/xpcom/base/nsID.cpp index 41dff1a225d..bc47708d3fa 100644 --- a/mozilla/xpcom/base/nsID.cpp +++ b/mozilla/xpcom/base/nsID.cpp @@ -34,7 +34,7 @@ static const char gIDFormat2[] = * an nsID */ -NS_COM PRBool nsID::Parse(char *aIDStr) +NS_COM PRBool nsID::Parse(const char *aIDStr) { PRInt32 count = 0; PRInt32 n1, n2, n3[8]; diff --git a/mozilla/xpcom/base/nsID.h b/mozilla/xpcom/base/nsID.h index b320ee38c53..35ea5ce5399 100644 --- a/mozilla/xpcom/base/nsID.h +++ b/mozilla/xpcom/base/nsID.h @@ -71,7 +71,7 @@ struct nsID { * nsID Parsing method. Turns a {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} * string into an nsID */ - NS_COM PRBool Parse(char *aIDStr); + NS_COM PRBool Parse(const char *aIDStr); /** * nsID string encoder. Returns an allocated string in diff --git a/mozilla/xpcom/build/nsXPComInit.cpp b/mozilla/xpcom/build/nsXPComInit.cpp index 62b15afbe15..e773237818d 100644 --- a/mozilla/xpcom/build/nsXPComInit.cpp +++ b/mozilla/xpcom/build/nsXPComInit.cpp @@ -543,6 +543,12 @@ nsresult NS_COM NS_ShutdownXPCOM(nsIServiceManager* servMgr) NS_ASSERTION(NS_SUCCEEDED(rv), "Component Manager shutdown failed."); #endif + // Release our own singletons + // Do this _after_ shutting down the component manager, because the + // JS component loader will use XPConnect to call nsIModule::canUnload, + // and that will spin up the InterfaceInfoManager again -- bad mojo + XPTI_FreeInterfaceInfoManager(); + // Finally, release the component manager last because it unloads the // libraries: NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt); diff --git a/mozilla/xpcom/components/nsCategoryManager.js b/mozilla/xpcom/components/nsCategoryManager.js index ed8ebd40850..b853f7ced4e 100644 --- a/mozilla/xpcom/components/nsCategoryManager.js +++ b/mozilla/xpcom/components/nsCategoryManager.js @@ -87,10 +87,9 @@ proto.addCategoryEntry = function (category, entry, value, persist, replace) { function deleteEntryFromRegistry(category, entry) { - dump("(not) deleting " + category + "[" + entry + "] from reg\n"); try { var categorySubtree = registry.getSubtreeRaw(categoriesKey, category); - /* registry.deleteValue(categorySubtree, entry); */ + registry.deleteValue(categorySubtree, entry); } catch (e : e instanceof Components.interfaces.nsIXPCException && e.result === 0x80510003 /* XXX NS_ERROR_REG_NOT_FOUND */) { @@ -124,18 +123,14 @@ function deleteCategoryFromRegistry(category) { proto.deleteCategory = function (category, persist) { delete this.categories[category]; /* - * Don't check for delete success, because persist means to remove from - * registry, even if someone has already done a non-persistent removal - * before. + * Don't check for delete success above, because persist means to + * remove from registry, even if someone has already done a + * non-persistent removal before. */ if (persist) deleteCategoryFromRegistry(category); }; -function CategoryEnumerator(category) { - this.category = category; -}; - proto.enumerateCategory = function (category) { return new CategoryEnumerator(this.categories[category] || { }); } @@ -235,6 +230,29 @@ proto.loadRegistryData = function() { } } +function CategoryEnumerator(category) { + this.contents = contents = []; + for (var i in category.table) + contents.push(i); +}; + +CategoryEnumerator.prototype = { + hasMoreElements: function() { + return this.index !== this.contents.length; + }, + + getNext: function() { + if (!this.hasMoreElements()) + return null; // XXX? + var str = Components.classes["component://netscape/supports-string"] + .createInterface(Components.interfaces.nsISupportsString); + str.data = this.contents[this.index++]; + return str; + }, + + index: 0 +}; + var module = { registerSelf: function (compMgr, fileSpec, location, type) { compMgr.registerComponentWithType(this.myCID, diff --git a/mozilla/xpcom/components/nsComponentManager.cpp b/mozilla/xpcom/components/nsComponentManager.cpp index 231a8e4fdaf..5afd44d1582 100644 --- a/mozilla/xpcom/components/nsComponentManager.cpp +++ b/mozilla/xpcom/components/nsComponentManager.cpp @@ -32,6 +32,7 @@ #include "nsISupportsPrimitives.h" #include "nsIComponentLoader.h" #include "nsNativeComponentLoader.h" +#include "nsXPIDLString.h" #include "plstr.h" #include "prlink.h" @@ -130,8 +131,8 @@ nsCID_Destroy(nsHashKey *aKey, void *aData, void* closure); //////////////////////////////////////////////////////////////////////////////// nsFactoryEntry::nsFactoryEntry(const nsCID &aClass, - char *aLocation, - char *aType, + const char *aLocation, + const char *aType, nsIComponentLoader *aLoader) : cid(aClass), factory(nsnull), loader(aLoader) { @@ -141,7 +142,7 @@ nsFactoryEntry::nsFactoryEntry(const nsCID &aClass, } nsFactoryEntry::nsFactoryEntry(const nsCID &aClass, nsIFactory *aFactory) - : cid(aClass), location(nsnull), type(nsnull), loader(nsnull) + : cid(aClass), loader(nsnull) { factory = aFactory; @@ -151,43 +152,8 @@ nsFactoryEntry::~nsFactoryEntry(void) { factory = 0; loader = 0; - if (location) - nsAllocator::Free(location); - if (type) - nsAllocator::Free(type); } -//////////////////////////////////////////////////////////////////////////////// -// autoStringFree -//////////////////////////////////////////////////////////////////////////////// - -// -// To prevent leaks, we are using this class. Typical use would be -// for each ptr to be deleted, create an object of these types with that ptr. -// Once that object goes out of scope, deletion and hence memory free will -// automatically happen. -// -class autoStringFree -{ -public: - enum DeleteModel { - NSPR_Delete = 1, - nsCRT_String_Delete = 2 - }; - autoStringFree(char *Ptr, DeleteModel whichDelete): mPtr(Ptr), mWhichDelete(whichDelete) {} - ~autoStringFree() { - if (mPtr) - if (mWhichDelete == NSPR_Delete) { PR_FREEIF(mPtr); } - else if (mWhichDelete == nsCRT_String_Delete) nsCRT::free(mPtr); - else PR_ASSERT(0); - } -private: - char *mPtr; - DeleteModel mWhichDelete; - -}; - - //////////////////////////////////////////////////////////////////////////////// // nsComponentManagerImpl //////////////////////////////////////////////////////////////////////////////// @@ -474,17 +440,18 @@ nsComponentManagerImpl::PlatformVersionCheck() if (NS_FAILED(rv)) return rv; - char *buf; - nsresult err = mRegistry->GetString(xpcomKey, versionValueName, &buf); - autoStringFree delete_buf(buf, autoStringFree::NSPR_Delete); + nsXPIDLCString buf; + nsresult err = mRegistry->GetString(xpcomKey, versionValueName, + getter_Copies(buf)); // If there is a version mismatch or no version string, we got an old registry. // Delete the old repository hierarchies and recreate version string if (NS_FAILED(err) || PL_strcmp(buf, NS_XPCOM_COMPONENT_MANAGER_VERSION_STRING)) { PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS, - ("nsComponentManager: Registry version mismatch (%s vs %s). Nuking xpcom " - "registry hierarchy.", buf, NS_XPCOM_COMPONENT_MANAGER_VERSION_STRING)); + ("nsComponentManager: Registry version mismatch (%s vs %s)." + "Nuking xpcom registry hierarchy.", (const char *)buf, + NS_XPCOM_COMPONENT_MANAGER_VERSION_STRING)); // Delete the XPCOM and CLSID hierarchy nsRegistryKey mozillaKey; @@ -708,28 +675,25 @@ nsComponentManagerImpl::PlatformFind(const nsCID &aCID, nsFactoryEntry* *result) if (NS_FAILED(rv)) return rv; - char *library = NULL; - rv = mRegistry->GetString(cidKey, inprocServerValueName, &library); + nsXPIDLCString library; + rv = mRegistry->GetString(cidKey, inprocServerValueName, + getter_Copies(library)); if (NS_FAILED(rv)) { // Registry inconsistent. No File name for CLSID. return rv; } - autoStringFree delete_library(library, autoStringFree::NSPR_Delete); + nsXPIDLCString componentType; + rv = mRegistry->GetString(cidKey, componentTypeValueName, + getter_Copies(componentType)); - char *componentType = NULL; - rv = mRegistry->GetString(cidKey, componentTypeValueName, &componentType); - if (rv == NS_ERROR_REG_NOT_FOUND) { + if (NS_FAILED(rv)) + if (rv == NS_ERROR_REG_NOT_FOUND) /* missing componentType, we assume application/x-moz-native */ - componentType = PL_strdup(nativeComponentType); - if (!componentType) - return NS_ERROR_OUT_OF_MEMORY; - } else if (NS_FAILED(rv)) { + componentType = nativeComponentType; + else return rv; // XXX translate error code? - } - - autoStringFree delete_type(componentType, autoStringFree::NSPR_Delete); nsCOMPtr loader; @@ -824,10 +788,9 @@ nsresult nsComponentManagerImpl::PlatformPrePopulateRegistry() if (!node) continue; // Get library name - char *cidString = NULL; - rv = node->GetName(&cidString); + nsXPIDLCString cidString; + rv = node->GetName(getter_Copies(cidString)); if (NS_FAILED(rv)) continue; - autoStringFree delete_cidString(cidString, autoStringFree::nsCRT_String_Delete); // Get key associated with library nsRegistryKey cidKey; @@ -835,19 +798,20 @@ nsresult nsComponentManagerImpl::PlatformPrePopulateRegistry() if (NS_FAILED(rv)) continue; // Create the CID entry - char *library = NULL; - rv = mRegistry->GetString(cidKey, inprocServerValueName, &library); + nsXPIDLCString library; + rv = mRegistry->GetString(cidKey, inprocServerValueName, + getter_Copies(library)); if (NS_FAILED(rv)) continue; nsCID aClass; + if (!(aClass.Parse(cidString))) continue; - char *componentType; + nsXPIDLCString componentType; if (NS_FAILED(mRegistry->GetString(cidKey, componentTypeValueName, - &componentType))) + getter_Copies(componentType)))) continue; nsFactoryEntry* entry = - /* hand off componentType and library to factory */ new nsFactoryEntry(aClass, library, componentType, nsCRT::strcmp(componentType, nativeComponentType) ? @@ -878,19 +842,20 @@ nsresult nsComponentManagerImpl::PlatformPrePopulateRegistry() if (NS_FAILED(rv)) continue; // Get the progid string - char *progidString = NULL; - rv = node->GetName(&progidString); + nsXPIDLCString progidString; + rv = node->GetName(getter_Copies(progidString)); if (NS_FAILED(rv)) continue; - autoStringFree delete_progidString(progidString, autoStringFree::nsCRT_String_Delete); // Get cid string nsRegistryKey progidKey; rv = node->GetKey(&progidKey); if (NS_FAILED(rv)) continue; - char *cidString = NULL; - rv = mRegistry->GetString(progidKey, classIDValueName, &cidString); + + nsXPIDLCString cidString; + rv = mRegistry->GetString(progidKey, classIDValueName, + getter_Copies(cidString)); if (NS_FAILED(rv)) continue; - autoStringFree delete_cidString(cidString, autoStringFree::NSPR_Delete); + nsCID *aClass = new nsCID(); if (!aClass) continue; // Protect against out of memory. if (!(aClass->Parse(cidString))) @@ -1038,7 +1003,7 @@ nsComponentManagerImpl::LoadFactory(nsFactoryEntry *aEntry, if (NS_FAILED(rv)) { PR_LOG(nsComponentManagerLog, PR_LOG_ERROR, ("nsComponentManager: failed to load factory from %s (%s)\n", - aEntry->location, aEntry->type)); + (const char *)aEntry->location, (const char *)aEntry->type)); return rv; } @@ -1054,8 +1019,8 @@ nsComponentManagerImpl::GetFactoryEntry(const nsCID &aClass, PRBool checkRegistr if (entry) { PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS, - ("\t\tfound %s as %p in factory cache.", entry->location, - entry)); + ("\t\tfound %s as %p in factory cache.", + (const char *)entry->location, entry)); } else { #ifdef USE_REGISTRY if (checkRegistry) @@ -1619,17 +1584,12 @@ nsComponentManagerImpl::RegisterComponentCommon(const nsCID &aClass, goto out; } - /* hand off aRegistryName to entry */ - newEntry = new nsFactoryEntry(aClass, aRegistryName, - nsCRT::strdup(aType), - loader); + newEntry = new nsFactoryEntry(aClass, aRegistryName, aType, loader); if (!newEntry) { rv = NS_ERROR_OUT_OF_MEMORY; goto out; } - aRegistryName = nsnull; // handed to nsFactoryEntry, so don't free - if (entry) { // aReplace implicit from test above delete entry; } @@ -1637,6 +1597,7 @@ nsComponentManagerImpl::RegisterComponentCommon(const nsCID &aClass, /* unless the fabric of the universe bends, we'll get entry back */ sanity = (entry == mFactories->Put(&key, newEntry)); PR_ASSERT(sanity); + /* don't try to clean up, just drop everything and run */ if (!sanity) return NS_ERROR_FACTORY_NOT_REGISTERED; @@ -1670,7 +1631,8 @@ nsComponentManagerImpl::RegisterComponentCommon(const nsCID &aClass, goto out; } - PR_LOG(nsComponentManagerLog, PR_LOG_WARNING, + PR_LOG(nsComponentManagerLog, + NS_SUCCEEDED(rv) ? PR_LOG_DEBUG : PR_LOG_ERROR, ("\t\tFactory register %s progID=%s.", NS_SUCCEEDED(rv) ? "succeeded" : "failed", aProgID ? aProgID : "")); @@ -1710,7 +1672,7 @@ nsComponentManagerImpl::GetLoaderForType(const char *aType, if (NS_FAILED(rv)) return rv; -#ifdef DEBUG_shaver +#ifdef DEBUG_shaver_off fprintf(stderr, "nCMI: constructing loader for type %s = %s\n", aType, progID); #endif @@ -1741,7 +1703,7 @@ nsComponentManagerImpl::RegisterComponentLoader(const char *aType, const char *a rv = mRegistry->SetString(loaderKey, progIDValueName, aProgID); -#ifdef DEBUG_shaver +#ifdef DEBUG_shaver_off fprintf(stderr, "nNCI: registered %s as component loader for %s\n", aProgID, aType); #endif @@ -2014,28 +1976,39 @@ struct AutoReg_closure { nsIFileSpec *spec; nsresult status; // this is a hack around Enumerate's void return nsIComponentLoader *native; + PRBool registered; }; static PRBool AutoRegister_enumerate(nsHashKey *key, void *aData, void *aClosure) { - nsIComponentLoader *loader = (nsIComponentLoader *)aData; + nsIComponentLoader *loader = NS_STATIC_CAST(nsIComponentLoader *, aData); struct AutoReg_closure *closure = (struct AutoReg_closure *)aClosure; - if (loader == closure->native) { -#ifdef DEBUG_shaver - fprintf(stderr, "AutoRegister_enumerate: skipping native\n"); -#endif + if (loader == closure->native) return PR_TRUE; - } PR_ASSERT(NS_SUCCEEDED(closure->status)); - closure->status = loader->AutoRegisterComponents(closure->when, closure->spec); - if (NS_FAILED(closure->status)) - return PR_FALSE; - return PR_TRUE; + closure->status = loader->AutoRegisterComponents(closure->when, + closure->spec); + return NS_SUCCEEDED(closure->status) ? PR_TRUE : PR_FALSE; +} + +static PRBool +RegisterDeferred_enumerate(nsHashKey *key, void *aData, void *aClosure) +{ + nsIComponentLoader *loader = NS_STATIC_CAST(nsIComponentLoader *, aData); + struct AutoReg_closure *closure = + (struct AutoReg_closure *)aClosure; + PR_ASSERT(NS_SUCCEEDED(closure->status)); + + PRBool registered; + closure->status = loader->RegisterDeferredComponents(closure->when, + ®istered); + closure->registered |= registered; + return NS_SUCCEEDED(closure->status) ? PR_TRUE : PR_FALSE; } nsresult @@ -2082,24 +2055,16 @@ nsComponentManagerImpl::AutoRegister(PRInt32 when, nsIFileSpec *inDirSpec) if (NS_FAILED(rv)) continue; - char *type; - rv = node->GetName(&type); + nsXPIDLCString type; + rv = node->GetName(getter_Copies(type)); if (NS_FAILED(rv)) continue; - autoStringFree del_type(type, autoStringFree::nsCRT_String_Delete); nsStringKey typeKey(type); - nsCOMPtr loader = - (nsIComponentLoader *)mLoaders->Get(&typeKey); - if (loader.get()) - continue; - -#ifdef DEBUG_shaver - fprintf(stderr, "nCMI: creating %s loader for enumeration\n", - type); -#endif - /* this will get it added to the hashtable and stuff */ + nsCOMPtr loader; + /* this will create it if we haven't already */ GetLoaderForType(type, getter_AddRefs(loader)); + continue; } @@ -2112,6 +2077,14 @@ nsComponentManagerImpl::AutoRegister(PRInt32 when, nsIFileSpec *inDirSpec) closure.native = mNativeComponentLoader; // prevent duplicate autoreg mLoaders->Enumerate(AutoRegister_enumerate, &closure); + if (NS_FAILED(closure.status)) + return closure.status; + + do { + closure.registered = PR_FALSE; + mLoaders->Enumerate(RegisterDeferred_enumerate, &closure); + } while (NS_SUCCEEDED(closure.status) && closure.registered); + return closure.status; } diff --git a/mozilla/xpcom/components/nsComponentManager.h b/mozilla/xpcom/components/nsComponentManager.h index d1de10c8823..350d1c29005 100644 --- a/mozilla/xpcom/components/nsComponentManager.h +++ b/mozilla/xpcom/components/nsComponentManager.h @@ -33,6 +33,7 @@ #include "prmon.h" #include "nsCOMPtr.h" #include "nsWeakReference.h" +#include "nsXPIDLString.h" class nsFactoryEntry; class nsDll; @@ -182,8 +183,8 @@ protected: class nsFactoryEntry { public: - nsFactoryEntry(const nsCID &aClass, char *location, char *aType, - nsIComponentLoader *aLoader); + nsFactoryEntry(const nsCID &aClass, const char *location, + const char *aType, nsIComponentLoader *aLoader); nsFactoryEntry(const nsCID &aClass, nsIFactory *aFactory); ~nsFactoryEntry(); @@ -209,9 +210,9 @@ public: } nsCID cid; - char *location; + nsXPIDLCString location; nsCOMPtr factory; - char *type; + nsXPIDLCString type; nsCOMPtr loader; }; diff --git a/mozilla/xpcom/components/nsIComponentLoader.idl b/mozilla/xpcom/components/nsIComponentLoader.idl index 567577a732e..1f51ee74420 100644 --- a/mozilla/xpcom/components/nsIComponentLoader.idl +++ b/mozilla/xpcom/components/nsIComponentLoader.idl @@ -27,23 +27,22 @@ interface nsIComponentLoader : nsISupports { /** * Get the factory for a given component. */ - nsIFactory GetFactory(in nsIIDRef aCID, in string aLocation, + nsIFactory getFactory(in nsIIDRef aCID, in string aLocation, in string aType); /** * Initialize the loader. * * We use nsISupports here because nsIRegistry isn't IDLized yet. - * Should we pass in a service manager reference too/instead? */ - void Init(in nsIComponentManager aCompMgr, in nsISupports aRegistry); + void init(in nsIComponentManager aCompMgr, in nsISupports aRegistry); /** * Called when a component of the appropriate type is registered, * to give the component loader an opportunity to do things like * annotate the registry and such. */ - void OnRegister(in nsIIDRef aCID, in string aType, + void onRegister(in nsIIDRef aCID, in string aType, in string aClassName, in string aProgID, in string aLocation, in boolean aReplace, in boolean aPersist); @@ -58,7 +57,7 @@ interface nsIComponentLoader : nsISupports { /** * AutoRegister components in the given directory. */ - void AutoRegisterComponents(in long aWhen, in nsIFileSpec aDirectory); + void autoRegisterComponents(in long aWhen, in nsIFileSpec aDirectory); /** * AutoRegister the given component. @@ -67,11 +66,17 @@ interface nsIComponentLoader : nsISupports { * attempt to register the component (wrong type) and ``throws'' an * NS_FAILED code if there was an error during registration. */ - boolean AutoRegisterComponent(in long aWhen, in nsIFileSpec aComponent); + boolean autoRegisterComponent(in long aWhen, in nsIFileSpec aComponent); + + /** + * Register any deferred (NS_ERROR_FACTORY_REGISTER_AGAIN) components. + * Return registered-any-components? + */ + boolean registerDeferredComponents(in long aWhen); /** * Unload all components that are willing. */ - void UnloadAll(in long aWhen); + void unloadAll(in long aWhen); }; diff --git a/mozilla/xpcom/components/nsNativeComponentLoader.cpp b/mozilla/xpcom/components/nsNativeComponentLoader.cpp index 7d3b3819e6c..0b6800c5497 100644 --- a/mozilla/xpcom/components/nsNativeComponentLoader.cpp +++ b/mozilla/xpcom/components/nsNativeComponentLoader.cpp @@ -28,6 +28,7 @@ #include "xcDll.h" #include "nsHashtable.h" #include "nsHashtableEnumerator.h" +#include "nsXPIDLString.h" #define PRINT_CRITICAL_ERROR_TO_SCREEN 1 #define USE_REGISTRY 1 @@ -35,33 +36,6 @@ extern PRLogModuleInfo *nsComponentManagerLog; -/* XXX consolidate with one in nsComponentManager.cpp */ -// -// To prevent leaks, we are using this class. Typical use would be -// for each ptr to be deleted, create an object of these types with that ptr. -// Once that object goes out of scope, deletion and hence memory free will -// automatically happen. -// -class autoStringFree -{ -public: - enum DeleteModel { - NSPR_Delete = 1, - nsCRT_String_Delete = 2 - }; - autoStringFree(char *Ptr, DeleteModel whichDelete): mPtr(Ptr), mWhichDelete(whichDelete) {} - ~autoStringFree() { - if (mPtr) - if (mWhichDelete == NSPR_Delete) { PR_FREEIF(mPtr); } - else if (mWhichDelete == nsCRT_String_Delete) nsCRT::free(mPtr); - else PR_ASSERT(0); - } -private: - char *mPtr; - DeleteModel mWhichDelete; - -}; - nsNativeComponentLoader::nsNativeComponentLoader() : mRegistry(nsnull), mCompMgr(nsnull), mDllStore(nsnull) { @@ -140,6 +114,14 @@ nsNativeComponentLoader::GetFactory(const nsIID & aCID, if (NS_FAILED(rv)) { if (rv == NS_ERROR_FACTORY_NOT_LOADED) { rv = GetFactoryFromNSGetFactory(dll, aCID, serviceMgr, _retval); +#ifdef WARN_ABOUT_NSGETFACTORY + if (NS_SUCCEEDED(rv)) { + fprintf(stderr, + "XPCOM: Component %s uses DEPRECATED\n" + " NSGetFactory interface. This could break " + "AT ANY TIME.\n", dll->GetNativePath()); + } +#endif } } #endif @@ -166,10 +148,6 @@ nsNativeComponentLoader::Init(nsIComponentManager *aCompMgr, nsISupports *aReg) { nsresult rv; -#ifdef DEBUG_shaver - fprintf(stderr, "nNCL: Init()\n"); -#endif - mCompMgr = aCompMgr; mRegistry = do_QueryInterface(aReg); if (!mCompMgr || !mRegistry) @@ -177,23 +155,15 @@ nsNativeComponentLoader::Init(nsIComponentManager *aCompMgr, nsISupports *aReg) rv = mRegistry->GetSubtree(nsIRegistry::Common, xpcomKeyName, &mXPCOMKey); - if (NS_FAILED(rv)) { -#ifdef DEBUG_shaver - fprintf(stderr, "nsNCL::Init: registry is hosed\n"); -#endif + if (NS_FAILED(rv)) return rv; - } if (!mDllStore) { mDllStore = new nsObjectHashtable(nsnull, nsnull, // never copy nsDll_Destroy, nsnull, 256, /* Thead Safe */ PR_TRUE); - if (!mDllStore) { -#ifdef DEBUG_shaver - fprintf(stderr, "nNCL::Init: couldn't build hash table\n"); -#endif + if (!mDllStore) return NS_ERROR_OUT_OF_MEMORY; - } } @@ -216,10 +186,9 @@ nsNativeComponentLoader::Init(nsIComponentManager *aCompMgr, nsISupports *aReg) if (NS_FAILED(rv)) continue; // Get library name - char *library = NULL; - rv = node->GetName(&library); + nsXPIDLCString library; + rv = node->GetName(getter_Copies(library)); if (NS_FAILED(rv)) continue; - autoStringFree delete_library(library, autoStringFree::nsCRT_String_Delete); // Get key associated with library nsRegistryKey libKey; @@ -441,10 +410,12 @@ nsFreeLibraryEnum(nsHashKey *aKey, void *aData, void* closure) * */ nsresult -nsNativeComponentLoader::SelfRegisterDll(nsDll *dll, const char *registryLocation) +nsNativeComponentLoader::SelfRegisterDll(nsDll *dll, + const char *registryLocation, + PRBool deferred) { - // Precondition: dll is not loaded already - PR_ASSERT(dll->IsLoaded() == PR_FALSE); + // Precondition: dll is not loaded already, unless we're deferred + PR_ASSERT(deferred || dll->IsLoaded() == PR_FALSE); nsIServiceManager* serviceMgr = NULL; nsresult res = nsServiceManager::GetGlobalServiceManager(&serviceMgr); @@ -505,8 +476,14 @@ nsNativeComponentLoader::SelfRegisterDll(nsDll *dll, const char *registryLocatio #endif /* OBSOLETE_MODULE_LOADING */ // Update the timestamp and size of the dll in registry - dll->Sync(); - SetRegistryDllInfo(registryLocation, dll->GetLastModifiedTime(), dll->GetSize()); + // Don't enter deferred modules in the registry, because it might only be + // able to register on some later autoreg, after another component has been + // installed. + if (res != NS_ERROR_FACTORY_REGISTER_AGAIN) { + dll->Sync(); + SetRegistryDllInfo(registryLocation, dll->GetLastModifiedTime(), + dll->GetSize()); + } return res; } @@ -573,7 +550,7 @@ nsNativeComponentLoader::DumpLoadError(nsDll *dll, #endif // MOZ_DEMANGLE_SYMBOLS // Do NSPR log - PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS, + PR_LOG(nsComponentManagerLog, PR_LOG_ERROR, ("nsNativeComponentLoader: %s(%s) Load FAILED with error:%s", aCallerName, dll->GetNativePath(), @@ -656,12 +633,12 @@ nsNativeComponentLoader::AutoRegisterComponent(PRInt32 when, /* this should be a pref or registry entry, or something */ const char *ValidDllExtensions[] = { ".dll", /* Windows */ + ".so", /* Unix */ + ".shlb", /* Mac ? */ ".dso", /* Unix ? */ ".dylib", /* Unix: Rhapsody */ - ".so", /* Unix */ ".so.1.0", /* Unix: BSD */ ".sl", /* Unix: HP-UX */ - ".shlb", /* Mac ? */ #if defined(VMS) ".exe", /* Open VMS */ #endif @@ -731,21 +708,12 @@ nsNativeComponentLoader::AutoRegisterComponent(PRInt32 when, // Skip invalid extensions return NS_OK; - - /* - * Get the name of the dll - * I think I get to go through every type of string here. - * Pink would be so proud. - */ - char *persistentDescriptor; - rv = mCompMgr->RegistryLocationForSpec(component, &persistentDescriptor); + nsXPIDLCString persistentDescriptor; + rv = mCompMgr->RegistryLocationForSpec(component, + getter_Copies(persistentDescriptor)); if (NS_FAILED(rv)) return rv; - autoStringFree - delete_persistentDescriptor(persistentDescriptor, - autoStringFree::nsCRT_String_Delete); - nsStringKey key(persistentDescriptor); // Get the registry representation of the dll, if any @@ -834,19 +802,19 @@ nsNativeComponentLoader::AutoRegisterComponent(PRInt32 when, // changed since we last saw it and it is unloaded successfully. // // Now we can try register the dll for sure. - nsresult res = SelfRegisterDll(dll, persistentDescriptor); - nsresult ret = NS_OK; + nsresult res = SelfRegisterDll(dll, persistentDescriptor, PR_FALSE); if (NS_FAILED(res)) { - PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS, - ("nsNativeComponentLoader: Autoregistration FAILED for " - "\"%s\". Skipping...", dll->GetNativePath())); - // Mark dll as not xpcom dll along with modified time and size in - // the registry so that we wont need to load the dll again every - // session until the dll changes. -#ifdef USE_REGISTRY -#endif /* USE_REGISTRY */ - ret = NS_ERROR_FAILURE; + if (res == NS_ERROR_FACTORY_REGISTER_AGAIN) { + /* defer for later loading */ + mDeferredComponents.AppendElement(dll); + return NS_OK; + } else { + PR_LOG(nsComponentManagerLog, PR_LOG_ERROR, + ("nsNativeComponentLoader: Autoregistration FAILED for " + "\"%s\". Skipping...", dll->GetNativePath())); + return NS_ERROR_FACTORY_NOT_REGISTERED; + } } else { @@ -857,7 +825,39 @@ nsNativeComponentLoader::AutoRegisterComponent(PRInt32 when, // registry happens at PlatformRegister(). No need to do it // here again. } - return ret; + return NS_OK; +} + +nsresult +nsNativeComponentLoader::RegisterDeferredComponents(PRInt32 aWhen, + PRBool *aRegistered) +{ + fprintf(stderr, "nNCL: registering deferred (%d)\n", + mDeferredComponents.Count()); + *aRegistered = PR_FALSE; + if (!mDeferredComponents.Count()) + return NS_OK; + + for (int i = mDeferredComponents.Count() - 1; i >= 0; i--) { + nsDll *dll = NS_STATIC_CAST(nsDll *, mDeferredComponents[i]); + nsresult rv = SelfRegisterDll(dll, + dll->GetRegistryLocation(), + PR_TRUE); + if (rv != NS_ERROR_FACTORY_REGISTER_AGAIN) { + if (NS_SUCCEEDED(rv)) + *aRegistered = PR_TRUE; + mDeferredComponents.RemoveElementAt(i); + } + } + + if (*aRegistered) + fprintf(stderr, "nNCL: registered deferred, %d left\n", + mDeferredComponents.Count()); + else + fprintf(stderr, "nNCL: didn't register any components, %d left\n", + mDeferredComponents.Count()); + /* are there any fatal errors? */ + return NS_OK; } nsresult diff --git a/mozilla/xpcom/components/nsNativeComponentLoader.h b/mozilla/xpcom/components/nsNativeComponentLoader.h index 24ee8a4f014..dc6790bc03c 100644 --- a/mozilla/xpcom/components/nsNativeComponentLoader.h +++ b/mozilla/xpcom/components/nsNativeComponentLoader.h @@ -25,6 +25,7 @@ #include "nsSpecialSystemDirectory.h" #include "nsCOMPtr.h" #include "nsHashtable.h" +#include "nsVoidArray.h" #include "xcDll.h" #ifndef nsNativeComponentLoader_h__ @@ -49,11 +50,13 @@ class nsNativeComponentLoader : public nsIComponentLoader { nsObjectHashtable* mDllStore; NS_IMETHOD RegisterComponentsInDir(PRInt32 when, nsIFileSpec *dir); nsRegistryKey mXPCOMKey; + nsVoidArray mDeferredComponents; private: nsresult CreateDll(nsIFileSpec *aSpec, const char *aLocation, PRUint32 modifiedTime, PRUint32 fileSize, nsDll **aDll); - nsresult SelfRegisterDll(nsDll *dll, const char *registryLocation); + nsresult SelfRegisterDll(nsDll *dll, const char *registryLocation, + PRBool deferred); nsresult SelfUnregisterDll(nsDll *dll); nsresult GetRegistryDllInfo(const char *aLocation, PRUint32 *lastModifiedTime, PRUint32 *fileSize); diff --git a/mozilla/xpcom/components/nsRegistry.cpp b/mozilla/xpcom/components/nsRegistry.cpp index 2000b2ebd3d..c764dc36d2b 100644 --- a/mozilla/xpcom/components/nsRegistry.cpp +++ b/mozilla/xpcom/components/nsRegistry.cpp @@ -27,6 +27,8 @@ #include "prmem.h" #include "prlock.h" #include "prlog.h" +#include "nsCRT.h" +#include "nsAllocator.h" /* extra locking for the paranoid */ /* #define EXTRA_THREADSAFE */ @@ -306,18 +308,6 @@ static void reginfo2Length( const REGINFO &in, PRUint32 &out ) { } } -/*-------------------------------- PR_strdup ----------------------------------- -| Utility function that does PR_Malloc and copies argument string. Caller | -| must do PR_Free. | -------------------------------------------------------------------------------*/ -static char *PR_strdup( const char *in ) { - char *result = (char*)PR_Malloc( strlen( in ) + 1 ); - if ( result ) { - strcpy( result, in ); - } - return result; -} - /*------------------------ nsISupports Implementation -------------------------- | This code generates the implementation of the nsISupports member functions | | for each class implemented in this file. | @@ -525,12 +515,8 @@ NS_IMETHODIMP nsRegistry::GetString( nsRegistryKey baseKey, const char *path, ch if ( err == REGERR_OK ) { - // Allocate buffer for return value - PRUint32 vallen = PL_strlen(regStr); - *result = (char*)PR_Malloc( vallen + 1 ); - if (*result) - PL_strcpy(*result, regStr); - else + *result = nsCRT::strdup(regStr); + if (!*result) rv = NS_ERROR_OUT_OF_MEMORY; } else if ( err == REGERR_BUFTOOSMALL ) @@ -541,7 +527,7 @@ NS_IMETHODIMP nsRegistry::GetString( nsRegistryKey baseKey, const char *path, ch // See if that worked. if( rv == NS_OK ) { - *result =(char*)PR_Malloc( length + 1 ); + *result =(char*)nsAllocator::Alloc( length + 1 ); if( *result ) { // Get string from registry into result buffer. @@ -554,7 +540,7 @@ NS_IMETHODIMP nsRegistry::GetString( nsRegistryKey baseKey, const char *path, ch if ( rv != NS_OK ) { // Didn't get result, free buffer - PR_Free( *result ); + nsCRT::free( *result ); *result = 0; } } @@ -1173,7 +1159,7 @@ nsRegistryNode::~nsRegistryNode() NS_IMETHODIMP nsRegistryNode::GetName( char **result ) { if (result == NULL) return NS_ERROR_NULL_POINTER; // Make sure there is a place to put the result. - *result = PR_strdup( mName ); + *result = nsCRT::strdup( mName ); if ( !*result ) return NS_ERROR_OUT_OF_MEMORY; return NS_OK; } @@ -1223,7 +1209,7 @@ NS_IMETHODIMP nsRegistryValue::GetName( char **result ) { rv = getInfo(); if( rv == NS_OK || rv == NS_ERROR_REG_NO_MORE ) { // worked, return actual result. - *result = PR_strdup( mName ); + *result = nsCRT::strdup( mName ); if ( *result ) { rv = NS_OK; } else { diff --git a/mozilla/xpcom/components/xcDll.h b/mozilla/xpcom/components/xcDll.h index 18d29e66ea2..ea1f3a28da6 100644 --- a/mozilla/xpcom/components/xcDll.h +++ b/mozilla/xpcom/components/xcDll.h @@ -109,6 +109,8 @@ public: const char *GetNativePath(void); // WARNING: DONT FREE string returned. const char *GetPersistentDescriptorString(void); + // WARNING: DONT FREE string returned. + const char *GetRegistryLocation(void) { return m_registryLocation; } PRUint32 GetLastModifiedTime(void) { return(m_modDate); } PRUint32 GetSize(void) { return(m_size); } PRLibrary *GetInstance(void) { return (m_instance); } diff --git a/mozilla/xpcom/ds/MANIFEST b/mozilla/xpcom/ds/MANIFEST index 49feaf790e5..d9901f575e4 100644 --- a/mozilla/xpcom/ds/MANIFEST +++ b/mozilla/xpcom/ds/MANIFEST @@ -17,6 +17,7 @@ nsQuickSort.h nsStr.h nsString.h nsString2.h +nsSupportsArray.h nsSupportsPrimitives.h nsTime.h nsUnitConversion.h diff --git a/mozilla/xpcom/ds/Makefile.in b/mozilla/xpcom/ds/Makefile.in index 0ab0218e456..35a9c4ad79b 100644 --- a/mozilla/xpcom/ds/Makefile.in +++ b/mozilla/xpcom/ds/Makefile.in @@ -83,6 +83,7 @@ EXPORTS = \ nsStr.h \ nsString.h \ nsString2.h \ + nsSupportsArray.h \ nsSupportsPrimitives.h \ nsTime.h \ nsUnitConversion.h \ diff --git a/mozilla/xpcom/ds/makefile.win b/mozilla/xpcom/ds/makefile.win index bfd84f7ba98..8936c68dd36 100644 --- a/mozilla/xpcom/ds/makefile.win +++ b/mozilla/xpcom/ds/makefile.win @@ -48,6 +48,7 @@ EXPORTS = \ nsStr.h \ nsString.h \ nsString2.h \ + nsSupportsArray.h \ nsSupportsPrimitives.h \ nsTime.h \ nsUnitConversion.h \ diff --git a/mozilla/xpcom/ds/nsIEnumerator.idl b/mozilla/xpcom/ds/nsIEnumerator.idl index 2f8ba1ef1e8..e3cdd90212d 100644 --- a/mozilla/xpcom/ds/nsIEnumerator.idl +++ b/mozilla/xpcom/ds/nsIEnumerator.idl @@ -28,8 +28,8 @@ [scriptable, uuid(D1899240-F9D2-11D2-BDD6-000064657374)] interface nsISimpleEnumerator : nsISupports { - boolean HasMoreElements(); - nsISupports GetNext(); + boolean hasMoreElements(); + nsISupports getNext(); }; /* @@ -67,11 +67,11 @@ interface nsIBidirectionalEnumerator : nsIEnumerator { /** Last will reset the list to the end. will return NS_FAILED if no items */ - void Last(); + void last(); /** Prev will decrement the list. will return failed if already at beginning */ - void Prev(); + void prev(); }; %{C++ diff --git a/mozilla/xpcom/glue/nsID.cpp b/mozilla/xpcom/glue/nsID.cpp index 41dff1a225d..bc47708d3fa 100644 --- a/mozilla/xpcom/glue/nsID.cpp +++ b/mozilla/xpcom/glue/nsID.cpp @@ -34,7 +34,7 @@ static const char gIDFormat2[] = * an nsID */ -NS_COM PRBool nsID::Parse(char *aIDStr) +NS_COM PRBool nsID::Parse(const char *aIDStr) { PRInt32 count = 0; PRInt32 n1, n2, n3[8]; diff --git a/mozilla/xpcom/glue/nsID.h b/mozilla/xpcom/glue/nsID.h index b320ee38c53..35ea5ce5399 100644 --- a/mozilla/xpcom/glue/nsID.h +++ b/mozilla/xpcom/glue/nsID.h @@ -71,7 +71,7 @@ struct nsID { * nsID Parsing method. Turns a {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} * string into an nsID */ - NS_COM PRBool Parse(char *aIDStr); + NS_COM PRBool Parse(const char *aIDStr); /** * nsID string encoder. Returns an allocated string in diff --git a/mozilla/xpcom/sample/nsSample.js b/mozilla/xpcom/sample/nsSample.js index f7d6130bbb5..32d8797dd43 100644 --- a/mozilla/xpcom/sample/nsSample.js +++ b/mozilla/xpcom/sample/nsSample.js @@ -44,6 +44,8 @@ mySample.prototype = { } var myModule = { + firstTime: true, + /* * RegisterSelf is called at registration time (component installation * or the only-until-release startup autoregistration) and is responsible @@ -53,6 +55,12 @@ var myModule = { * unmolested. */ registerSelf: function (compMgr, fileSpec, location, type) { + if (this.firstTime) { + dump("*** Deferring registration of sample JS components\n"); + this.firstTime = false; + throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN; + } + dump("*** Registering sample JS components\n"); compMgr.registerComponentWithType(this.myCID, "Sample JS Component", "mozilla.jssample.1", fileSpec, @@ -104,6 +112,22 @@ var myModule = { return new mySample(); } + }, + + /* + * canUnload is used to signal that the component is about to be unloaded. + * C++ components can return false to indicate that they don't wish to + * be unloaded, but the return value from JS components' canUnload is + * ignored: mark-and-sweep will keep everything around until it's no + * longer in use, making unconditional ``unload'' safe. + * + * You still need to provide a (likely useless) canUnload method, though: + * it's part of the nsIModule interface contract, and the JS loader _will_ + * call it. + */ + canUnload: function(compMgr) { + dump("*** Unloading sample JS components\n"); + return true; } }; diff --git a/mozilla/xpcom/tools/registry/regExport.cpp b/mozilla/xpcom/tools/registry/regExport.cpp index de5ea87a79e..ad06c1889ac 100644 --- a/mozilla/xpcom/tools/registry/regExport.cpp +++ b/mozilla/xpcom/tools/registry/regExport.cpp @@ -244,7 +244,7 @@ static void displayValues( nsIRegistry *reg, nsRegistryKey root ) { rv = reg->GetString( root, name, &strValue ); if ( rv == NS_OK ) { printString( strValue, strlen(name) ); - PR_Free( strValue ); + nsAllocator::Free( strValue ); } else { printf( "\t Error getting string value, rv=0x%08X", (int)rv ); } @@ -280,6 +280,7 @@ static void displayValues( nsIRegistry *reg, nsRegistryKey root ) { printf( "\t= ? (error getting value, rv=0x%08X)", (int)rv ); } printf("\n"); + nsAllocator::Free( name ); } else { printf( "Error getting value name, rv=0x%08X\n", (int)rv ); }