diff --git a/mozilla/xpcom/components/nsGenericFactory.cpp b/mozilla/xpcom/components/nsGenericFactory.cpp index 4beba6a7d67..89a7794ec7a 100644 --- a/mozilla/xpcom/components/nsGenericFactory.cpp +++ b/mozilla/xpcom/components/nsGenericFactory.cpp @@ -40,7 +40,7 @@ // DO NOT COPY THIS CODE INTO YOUR SOURCE! USE NS_IMPL_NSGETMODULE() #include "nsGenericFactory.h" -#include "nsCRT.h" +#include "nsMemory.h" #include "nsCOMPtr.h" #include "nsIComponentManager.h" #include "nsIComponentRegistrar.h" @@ -221,7 +221,7 @@ nsGenericModule::nsGenericModule(const char* moduleName, PRUint32 componentCount mModuleName(moduleName), mComponentCount(componentCount), mComponents(components), - mFactories(32, PR_FALSE), + mFactoriesNotToBeRegistered(nsnull), mCtor(ctor), mDtor(dtor) { @@ -235,9 +235,24 @@ nsGenericModule::~nsGenericModule() NS_IMPL_THREADSAFE_ISUPPORTS1(nsGenericModule, nsIModule) +nsresult +nsGenericModule::AddFactoryNode(nsIGenericFactory* fact) +{ + if (!fact) + return NS_ERROR_FAILURE; + + FactoryNode *node = new FactoryNode(fact, mFactoriesNotToBeRegistered); + if (!node) + return NS_ERROR_OUT_OF_MEMORY; + + mFactoriesNotToBeRegistered = node; + return NS_OK; +} + + // Perform our one-time intialization for this module nsresult -nsGenericModule::Initialize() +nsGenericModule::Initialize(nsIComponentManager *compMgr) { if (mInitialized) { return NS_OK; @@ -249,6 +264,11 @@ nsGenericModule::Initialize() return rv; } + nsresult rv; + nsCOMPtr registrar = do_QueryInterface(compMgr, &rv); + if (NS_FAILED(rv)) + return rv; + // Eagerly populate factory/class object hash for entries // without constructors. If we didn't, the class object would // never get created. Also create the factory, which doubles @@ -263,9 +283,18 @@ nsGenericModule::Initialize() nsCOMPtr fact; nsresult rv = NS_NewGenericFactory(getter_AddRefs(fact), desc); if (NS_FAILED(rv)) return rv; - - nsIDKey key(desc->mCID); - (void)mFactories.Put(&key, fact); + + // if we don't have a mConstructor, then we should not populate + // the component manager. + if (!desc->mConstructor) { + rv = AddFactoryNode(fact); + } else { + rv = registrar->RegisterFactory(desc->mCID, + desc->mDescription, + desc->mContractID, + fact); + } + if (NS_FAILED(rv)) return rv; } desc++; } @@ -278,8 +307,14 @@ nsGenericModule::Initialize() void nsGenericModule::Shutdown() { - // Release the factory objects - mFactories.Reset(); + // Free cached factories that were not registered. + FactoryNode* node; + while (mFactoriesNotToBeRegistered) + { + node = mFactoriesNotToBeRegistered->mNext; + delete mFactoriesNotToBeRegistered; + mFactoriesNotToBeRegistered = node; + } if (mInitialized) { mInitialized = PR_FALSE; @@ -306,7 +341,7 @@ nsGenericModule::GetClassObject(nsIComponentManager *aCompMgr, // Do one-time-only initialization if necessary if (!mInitialized) { - rv = Initialize(); + rv = Initialize(aCompMgr); if (NS_FAILED(rv)) { // Initialization failed! yikes! return rv; @@ -315,32 +350,24 @@ nsGenericModule::GetClassObject(nsIComponentManager *aCompMgr, // Choose the appropriate factory, based on the desired instance // class type (aClass). - nsIDKey key(aClass); - nsCOMPtr fact = getter_AddRefs(NS_REINTERPRET_CAST(nsIGenericFactory *, mFactories.Get(&key))); - if (fact == nsnull) { - const nsModuleComponentInfo* desc = mComponents; - for (PRUint32 i = 0; i < mComponentCount; i++) { - if (desc->mCID.Equals(aClass)) { - rv = NS_NewGenericFactory(getter_AddRefs(fact), desc); - if (NS_FAILED(rv)) return rv; - - (void)mFactories.Put(&key, fact); - goto found; - } - desc++; + const nsModuleComponentInfo* desc = mComponents; + for (PRUint32 i = 0; i < mComponentCount; i++) { + if (desc->mCID.Equals(aClass)) { + nsCOMPtr fact; + rv = NS_NewGenericFactory(getter_AddRefs(fact), desc); + if (NS_FAILED(rv)) return rv; + return fact->QueryInterface(aIID, r_classObj); } - // not found in descriptions -#ifdef DEBUG - char* cs = aClass.ToString(); - printf("+++ nsGenericModule %s: unable to create factory for %s\n", mModuleName, cs); - nsCRT::free(cs); -#endif - // XXX put in stop-gap so that we don't search for this one again - return NS_ERROR_FACTORY_NOT_REGISTERED; + desc++; } - found: - rv = fact->QueryInterface(aIID, r_classObj); - return rv; + // not found in descriptions +#ifdef DEBUG + char* cs = aClass.ToString(); + printf("+++ nsGenericModule %s: unable to create factory for %s\n", mModuleName, cs); + // leak until we resolve the nsID Allocator. + // nsCRT::free(cs); +#endif // XXX put in stop-gap so that we don't search for this one again + return NS_ERROR_FACTORY_NOT_REGISTERED; } NS_IMETHODIMP diff --git a/mozilla/xpcom/components/nsGenericFactory.h b/mozilla/xpcom/components/nsGenericFactory.h index 2b3ec0042bb..b6f556cf655 100644 --- a/mozilla/xpcom/components/nsGenericFactory.h +++ b/mozilla/xpcom/components/nsGenericFactory.h @@ -38,6 +38,7 @@ #ifndef nsGenericFactory_h___ #define nsGenericFactory_h___ +#include "nsCOMPtr.h" #include "nsIGenericFactory.h" #include "nsIClassInfo.h" @@ -71,33 +72,53 @@ private: //////////////////////////////////////////////////////////////////////////////// #include "nsIModule.h" -#include "nsHashtable.h" +#include "plhash.h" class nsGenericModule : public nsIModule { public: - nsGenericModule(const char* moduleName, PRUint32 componentCount, + nsGenericModule(const char* moduleName, + PRUint32 componentCount, const nsModuleComponentInfo* components, nsModuleConstructorProc ctor, nsModuleDestructorProc dtor); + virtual ~nsGenericModule(); NS_DECL_ISUPPORTS NS_DECL_NSIMODULE + struct FactoryNode + { + FactoryNode(nsIGenericFactory* fact, FactoryNode* next) + { + mFactory = fact; + mNext = next; + } + ~FactoryNode(){} + + nsCOMPtr mFactory; + FactoryNode* mNext; + }; + + + + protected: - nsresult Initialize(); + nsresult Initialize(nsIComponentManager* compMgr); void Shutdown(); + nsresult AddFactoryNode(nsIGenericFactory* fact); - PRBool mInitialized; - const char* mModuleName; - PRUint32 mComponentCount; - const nsModuleComponentInfo* mComponents; - nsSupportsHashtable mFactories; - nsModuleConstructorProc mCtor; - nsModuleDestructorProc mDtor; + PRBool mInitialized; + const char* mModuleName; + PRUint32 mComponentCount; + const nsModuleComponentInfo* mComponents; + FactoryNode* mFactoriesNotToBeRegistered; + nsModuleConstructorProc mCtor; + nsModuleDestructorProc mDtor; }; #endif /* nsGenericFactory_h___ */ + diff --git a/mozilla/xpcom/glue/nsGenericFactory.cpp b/mozilla/xpcom/glue/nsGenericFactory.cpp index 4beba6a7d67..89a7794ec7a 100644 --- a/mozilla/xpcom/glue/nsGenericFactory.cpp +++ b/mozilla/xpcom/glue/nsGenericFactory.cpp @@ -40,7 +40,7 @@ // DO NOT COPY THIS CODE INTO YOUR SOURCE! USE NS_IMPL_NSGETMODULE() #include "nsGenericFactory.h" -#include "nsCRT.h" +#include "nsMemory.h" #include "nsCOMPtr.h" #include "nsIComponentManager.h" #include "nsIComponentRegistrar.h" @@ -221,7 +221,7 @@ nsGenericModule::nsGenericModule(const char* moduleName, PRUint32 componentCount mModuleName(moduleName), mComponentCount(componentCount), mComponents(components), - mFactories(32, PR_FALSE), + mFactoriesNotToBeRegistered(nsnull), mCtor(ctor), mDtor(dtor) { @@ -235,9 +235,24 @@ nsGenericModule::~nsGenericModule() NS_IMPL_THREADSAFE_ISUPPORTS1(nsGenericModule, nsIModule) +nsresult +nsGenericModule::AddFactoryNode(nsIGenericFactory* fact) +{ + if (!fact) + return NS_ERROR_FAILURE; + + FactoryNode *node = new FactoryNode(fact, mFactoriesNotToBeRegistered); + if (!node) + return NS_ERROR_OUT_OF_MEMORY; + + mFactoriesNotToBeRegistered = node; + return NS_OK; +} + + // Perform our one-time intialization for this module nsresult -nsGenericModule::Initialize() +nsGenericModule::Initialize(nsIComponentManager *compMgr) { if (mInitialized) { return NS_OK; @@ -249,6 +264,11 @@ nsGenericModule::Initialize() return rv; } + nsresult rv; + nsCOMPtr registrar = do_QueryInterface(compMgr, &rv); + if (NS_FAILED(rv)) + return rv; + // Eagerly populate factory/class object hash for entries // without constructors. If we didn't, the class object would // never get created. Also create the factory, which doubles @@ -263,9 +283,18 @@ nsGenericModule::Initialize() nsCOMPtr fact; nsresult rv = NS_NewGenericFactory(getter_AddRefs(fact), desc); if (NS_FAILED(rv)) return rv; - - nsIDKey key(desc->mCID); - (void)mFactories.Put(&key, fact); + + // if we don't have a mConstructor, then we should not populate + // the component manager. + if (!desc->mConstructor) { + rv = AddFactoryNode(fact); + } else { + rv = registrar->RegisterFactory(desc->mCID, + desc->mDescription, + desc->mContractID, + fact); + } + if (NS_FAILED(rv)) return rv; } desc++; } @@ -278,8 +307,14 @@ nsGenericModule::Initialize() void nsGenericModule::Shutdown() { - // Release the factory objects - mFactories.Reset(); + // Free cached factories that were not registered. + FactoryNode* node; + while (mFactoriesNotToBeRegistered) + { + node = mFactoriesNotToBeRegistered->mNext; + delete mFactoriesNotToBeRegistered; + mFactoriesNotToBeRegistered = node; + } if (mInitialized) { mInitialized = PR_FALSE; @@ -306,7 +341,7 @@ nsGenericModule::GetClassObject(nsIComponentManager *aCompMgr, // Do one-time-only initialization if necessary if (!mInitialized) { - rv = Initialize(); + rv = Initialize(aCompMgr); if (NS_FAILED(rv)) { // Initialization failed! yikes! return rv; @@ -315,32 +350,24 @@ nsGenericModule::GetClassObject(nsIComponentManager *aCompMgr, // Choose the appropriate factory, based on the desired instance // class type (aClass). - nsIDKey key(aClass); - nsCOMPtr fact = getter_AddRefs(NS_REINTERPRET_CAST(nsIGenericFactory *, mFactories.Get(&key))); - if (fact == nsnull) { - const nsModuleComponentInfo* desc = mComponents; - for (PRUint32 i = 0; i < mComponentCount; i++) { - if (desc->mCID.Equals(aClass)) { - rv = NS_NewGenericFactory(getter_AddRefs(fact), desc); - if (NS_FAILED(rv)) return rv; - - (void)mFactories.Put(&key, fact); - goto found; - } - desc++; + const nsModuleComponentInfo* desc = mComponents; + for (PRUint32 i = 0; i < mComponentCount; i++) { + if (desc->mCID.Equals(aClass)) { + nsCOMPtr fact; + rv = NS_NewGenericFactory(getter_AddRefs(fact), desc); + if (NS_FAILED(rv)) return rv; + return fact->QueryInterface(aIID, r_classObj); } - // not found in descriptions -#ifdef DEBUG - char* cs = aClass.ToString(); - printf("+++ nsGenericModule %s: unable to create factory for %s\n", mModuleName, cs); - nsCRT::free(cs); -#endif - // XXX put in stop-gap so that we don't search for this one again - return NS_ERROR_FACTORY_NOT_REGISTERED; + desc++; } - found: - rv = fact->QueryInterface(aIID, r_classObj); - return rv; + // not found in descriptions +#ifdef DEBUG + char* cs = aClass.ToString(); + printf("+++ nsGenericModule %s: unable to create factory for %s\n", mModuleName, cs); + // leak until we resolve the nsID Allocator. + // nsCRT::free(cs); +#endif // XXX put in stop-gap so that we don't search for this one again + return NS_ERROR_FACTORY_NOT_REGISTERED; } NS_IMETHODIMP diff --git a/mozilla/xpcom/glue/nsGenericFactory.h b/mozilla/xpcom/glue/nsGenericFactory.h index 2b3ec0042bb..b6f556cf655 100644 --- a/mozilla/xpcom/glue/nsGenericFactory.h +++ b/mozilla/xpcom/glue/nsGenericFactory.h @@ -38,6 +38,7 @@ #ifndef nsGenericFactory_h___ #define nsGenericFactory_h___ +#include "nsCOMPtr.h" #include "nsIGenericFactory.h" #include "nsIClassInfo.h" @@ -71,33 +72,53 @@ private: //////////////////////////////////////////////////////////////////////////////// #include "nsIModule.h" -#include "nsHashtable.h" +#include "plhash.h" class nsGenericModule : public nsIModule { public: - nsGenericModule(const char* moduleName, PRUint32 componentCount, + nsGenericModule(const char* moduleName, + PRUint32 componentCount, const nsModuleComponentInfo* components, nsModuleConstructorProc ctor, nsModuleDestructorProc dtor); + virtual ~nsGenericModule(); NS_DECL_ISUPPORTS NS_DECL_NSIMODULE + struct FactoryNode + { + FactoryNode(nsIGenericFactory* fact, FactoryNode* next) + { + mFactory = fact; + mNext = next; + } + ~FactoryNode(){} + + nsCOMPtr mFactory; + FactoryNode* mNext; + }; + + + + protected: - nsresult Initialize(); + nsresult Initialize(nsIComponentManager* compMgr); void Shutdown(); + nsresult AddFactoryNode(nsIGenericFactory* fact); - PRBool mInitialized; - const char* mModuleName; - PRUint32 mComponentCount; - const nsModuleComponentInfo* mComponents; - nsSupportsHashtable mFactories; - nsModuleConstructorProc mCtor; - nsModuleDestructorProc mDtor; + PRBool mInitialized; + const char* mModuleName; + PRUint32 mComponentCount; + const nsModuleComponentInfo* mComponents; + FactoryNode* mFactoriesNotToBeRegistered; + nsModuleConstructorProc mCtor; + nsModuleDestructorProc mDtor; }; #endif /* nsGenericFactory_h___ */ +