diff --git a/xpcom/components/nsGenericFactory.cpp b/xpcom/components/nsGenericFactory.cpp index a980bb33c25..9cc0194c998 100644 --- a/xpcom/components/nsGenericFactory.cpp +++ b/xpcom/components/nsGenericFactory.cpp @@ -100,12 +100,14 @@ NS_NewGenericFactory(nsIGenericFactory* *result, //////////////////////////////////////////////////////////////////////////////// nsGenericModule::nsGenericModule(const char* moduleName, PRUint32 componentCount, - nsModuleComponentInfo* components) + nsModuleComponentInfo* components, + nsModuleDestructorProc dtor) : mInitialized(PR_FALSE), mModuleName(moduleName), mComponentCount(componentCount), mComponents(components), - mFactories(8, PR_FALSE) + mFactories(8, PR_FALSE), + mDtor(dtor) { NS_INIT_ISUPPORTS(); } @@ -132,6 +134,8 @@ nsGenericModule::Initialize() void nsGenericModule::Shutdown() { + if (mDtor) + mDtor(this); // Release the factory objects mFactories.Reset(); } @@ -257,6 +261,7 @@ NS_COM nsresult NS_NewGenericModule(const char* moduleName, PRUint32 componentCount, nsModuleComponentInfo* components, + nsModuleDestructorProc dtor, nsIModule* *result) { nsresult rv = NS_OK; @@ -265,7 +270,7 @@ NS_NewGenericModule(const char* moduleName, // Create and initialize the module instance nsGenericModule *m = - new nsGenericModule(moduleName, componentCount, components); + new nsGenericModule(moduleName, componentCount, components, dtor); if (!m) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/xpcom/components/nsGenericFactory.h b/xpcom/components/nsGenericFactory.h index 64e7df7b5fd..15567249bfd 100644 --- a/xpcom/components/nsGenericFactory.h +++ b/xpcom/components/nsGenericFactory.h @@ -70,7 +70,8 @@ class nsGenericModule : public nsIModule { public: nsGenericModule(const char* moduleName, PRUint32 componentCount, - nsModuleComponentInfo* components); + nsModuleComponentInfo* components, + nsModuleDestructorProc dtor); virtual ~nsGenericModule(); NS_DECL_ISUPPORTS @@ -87,6 +88,7 @@ protected: PRUint32 mComponentCount; nsModuleComponentInfo* mComponents; nsSupportsHashtable mFactories; + nsModuleDestructorProc mDtor; }; #endif /* nsGenericFactory_h___ */ diff --git a/xpcom/components/nsIGenericFactory.h b/xpcom/components/nsIGenericFactory.h index 79e6bf370f2..80914d46079 100644 --- a/xpcom/components/nsIGenericFactory.h +++ b/xpcom/components/nsIGenericFactory.h @@ -85,20 +85,26 @@ struct nsModuleComponentInfo { nsIGenericFactory::ConstructorProcPtr mConstructor; }; +typedef void (PR_CALLBACK *nsModuleDestructorProc) (nsIModule *self); + extern NS_COM nsresult NS_NewGenericModule(const char* moduleName, PRUint32 componentCount, nsModuleComponentInfo* components, + nsModuleDestructorProc dtor, nsIModule* *result); #define NS_IMPL_NSGETMODULE(_name, _components) \ + NS_IMPL_NSGETMODULE_WITH_DTOR(_name, _components, nsnull) + +#define NS_IMPL_NSGETMODULE_WITH_DTOR(_name, _components, _dtor) \ extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr, \ nsIFileSpec* location, \ nsIModule** result) \ { \ return NS_NewGenericModule((_name), \ sizeof(_components) / sizeof(_components[0]), \ - (_components), result); \ + (_components), _dtor, result); \ } //////////////////////////////////////////////////////////////////////////////// @@ -167,4 +173,36 @@ _InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) return rv; \ } \ +// 'Constructor' that uses an existing getter function that gets a singleton. +// NOTE: assumes that getter does an AddRef - so additional AddRef is not done. +#define NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(_InstanceClass, _GetterProc) \ +static NS_IMETHODIMP \ +_InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) \ +{ \ + nsresult rv; \ + \ + _InstanceClass * inst; \ + \ + if (NULL == aResult) { \ + rv = NS_ERROR_NULL_POINTER; \ + return rv; \ + } \ + *aResult = NULL; \ + if (NULL != aOuter) { \ + rv = NS_ERROR_NO_AGGREGATION; \ + return rv; \ + } \ + \ + inst = _GetterProc(); \ + if (NULL == inst) { \ + rv = NS_ERROR_OUT_OF_MEMORY; \ + return rv; \ + } \ + /* NS_ADDREF(inst); */ \ + rv = inst->QueryInterface(aIID, aResult); \ + NS_RELEASE(inst); \ + \ + return rv; \ +} \ + #endif /* nsIGenericFactory_h___ */ diff --git a/xpcom/glue/nsGenericFactory.cpp b/xpcom/glue/nsGenericFactory.cpp index a980bb33c25..9cc0194c998 100644 --- a/xpcom/glue/nsGenericFactory.cpp +++ b/xpcom/glue/nsGenericFactory.cpp @@ -100,12 +100,14 @@ NS_NewGenericFactory(nsIGenericFactory* *result, //////////////////////////////////////////////////////////////////////////////// nsGenericModule::nsGenericModule(const char* moduleName, PRUint32 componentCount, - nsModuleComponentInfo* components) + nsModuleComponentInfo* components, + nsModuleDestructorProc dtor) : mInitialized(PR_FALSE), mModuleName(moduleName), mComponentCount(componentCount), mComponents(components), - mFactories(8, PR_FALSE) + mFactories(8, PR_FALSE), + mDtor(dtor) { NS_INIT_ISUPPORTS(); } @@ -132,6 +134,8 @@ nsGenericModule::Initialize() void nsGenericModule::Shutdown() { + if (mDtor) + mDtor(this); // Release the factory objects mFactories.Reset(); } @@ -257,6 +261,7 @@ NS_COM nsresult NS_NewGenericModule(const char* moduleName, PRUint32 componentCount, nsModuleComponentInfo* components, + nsModuleDestructorProc dtor, nsIModule* *result) { nsresult rv = NS_OK; @@ -265,7 +270,7 @@ NS_NewGenericModule(const char* moduleName, // Create and initialize the module instance nsGenericModule *m = - new nsGenericModule(moduleName, componentCount, components); + new nsGenericModule(moduleName, componentCount, components, dtor); if (!m) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/xpcom/glue/nsGenericFactory.h b/xpcom/glue/nsGenericFactory.h index 64e7df7b5fd..15567249bfd 100644 --- a/xpcom/glue/nsGenericFactory.h +++ b/xpcom/glue/nsGenericFactory.h @@ -70,7 +70,8 @@ class nsGenericModule : public nsIModule { public: nsGenericModule(const char* moduleName, PRUint32 componentCount, - nsModuleComponentInfo* components); + nsModuleComponentInfo* components, + nsModuleDestructorProc dtor); virtual ~nsGenericModule(); NS_DECL_ISUPPORTS @@ -87,6 +88,7 @@ protected: PRUint32 mComponentCount; nsModuleComponentInfo* mComponents; nsSupportsHashtable mFactories; + nsModuleDestructorProc mDtor; }; #endif /* nsGenericFactory_h___ */ diff --git a/xpcom/glue/nsIGenericFactory.h b/xpcom/glue/nsIGenericFactory.h index 79e6bf370f2..80914d46079 100644 --- a/xpcom/glue/nsIGenericFactory.h +++ b/xpcom/glue/nsIGenericFactory.h @@ -85,20 +85,26 @@ struct nsModuleComponentInfo { nsIGenericFactory::ConstructorProcPtr mConstructor; }; +typedef void (PR_CALLBACK *nsModuleDestructorProc) (nsIModule *self); + extern NS_COM nsresult NS_NewGenericModule(const char* moduleName, PRUint32 componentCount, nsModuleComponentInfo* components, + nsModuleDestructorProc dtor, nsIModule* *result); #define NS_IMPL_NSGETMODULE(_name, _components) \ + NS_IMPL_NSGETMODULE_WITH_DTOR(_name, _components, nsnull) + +#define NS_IMPL_NSGETMODULE_WITH_DTOR(_name, _components, _dtor) \ extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr, \ nsIFileSpec* location, \ nsIModule** result) \ { \ return NS_NewGenericModule((_name), \ sizeof(_components) / sizeof(_components[0]), \ - (_components), result); \ + (_components), _dtor, result); \ } //////////////////////////////////////////////////////////////////////////////// @@ -167,4 +173,36 @@ _InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) return rv; \ } \ +// 'Constructor' that uses an existing getter function that gets a singleton. +// NOTE: assumes that getter does an AddRef - so additional AddRef is not done. +#define NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(_InstanceClass, _GetterProc) \ +static NS_IMETHODIMP \ +_InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) \ +{ \ + nsresult rv; \ + \ + _InstanceClass * inst; \ + \ + if (NULL == aResult) { \ + rv = NS_ERROR_NULL_POINTER; \ + return rv; \ + } \ + *aResult = NULL; \ + if (NULL != aOuter) { \ + rv = NS_ERROR_NO_AGGREGATION; \ + return rv; \ + } \ + \ + inst = _GetterProc(); \ + if (NULL == inst) { \ + rv = NS_ERROR_OUT_OF_MEMORY; \ + return rv; \ + } \ + /* NS_ADDREF(inst); */ \ + rv = inst->QueryInterface(aIID, aResult); \ + NS_RELEASE(inst); \ + \ + return rv; \ +} \ + #endif /* nsIGenericFactory_h___ */