MXS-1512 Take module object type as template argument

Makes it possible to move the module object pointer into the
SpecificModule template.
This commit is contained in:
Johan Wikman
2017-11-22 10:23:34 +02:00
parent 8a10b72e4d
commit 7ae2acecf7
4 changed files with 46 additions and 26 deletions

View File

@ -23,14 +23,13 @@ namespace maxscale
/** /**
* An instance of FilterModule represents a filter module. * An instance of FilterModule represents a filter module.
*/ */
class FilterModule : public SpecificModule<FilterModule> class FilterModule : public SpecificModule<FilterModule, MXS_FILTER_OBJECT>
{ {
FilterModule(const FilterModule&); FilterModule(const FilterModule&);
FilterModule& operator = (const FilterModule&); FilterModule& operator = (const FilterModule&);
public: public:
static const char* zName; /*< The name describing the module type. */ static const char* zName; /*< The name describing the module type. */
typedef MXS_FILTER_OBJECT type_t; /*< The type of the module object. */
class Session; class Session;
class Instance class Instance
@ -184,15 +183,12 @@ private:
} }
private: private:
friend class SpecificModule<FilterModule>; friend Base;
FilterModule(MXS_FILTER_OBJECT* pApi) FilterModule(const MXS_MODULE* pModule)
: m_pApi(pApi) : Base(pModule)
{ {
} }
private:
MXS_FILTER_OBJECT* m_pApi;
}; };
} }

View File

@ -31,10 +31,20 @@ public:
* @param zFile_name The name of the module. * @param zFile_name The name of the module.
* @param zType_name The expected type of the module. * @param zType_name The expected type of the module.
* *
* @return The module object, if the module could be loaded, otherwise NULL. * @return The module specific entry point structure or NULL.
*/ */
static void* load(const char *zFile_name, const char *zType_name); static void* load(const char *zFile_name, const char *zType_name);
/**
* Get a module with a specific name, assumed to be of a specific type.
*
* @param zFile_name The name of the module.
* @param zType_name The expected type of the module.
*
* @return The loaded module, if the module could be loaded, otherwise NULL.
*/
static const MXS_MODULE* get(const char *zFile_name, const char *zType_name);
/** /**
* Perform process initialization of all modules. Should be called only * Perform process initialization of all modules. Should be called only
* when all modules intended to be loaded have been loaded. * when all modules intended to be loaded have been loaded.
@ -60,41 +70,55 @@ public:
* Perform thread finalization of all modules. * Perform thread finalization of all modules.
*/ */
static void thread_finish(); static void thread_finish();
protected:
Module(const MXS_MODULE* pModule)
: m_module(*pModule)
{
}
const MXS_MODULE& m_module;
}; };
/** /**
* The template Module is intended to be derived from using the derived * The template Module is intended to be derived from using the derived
* class as template argument. * class as template argument.
* *
* class XyzModule : public SpecificModule<XyzModule> { ... } * class XyzModule : public SpecificModule<XyzModule, XYZ_MODULE_OBJECT> { ... }
* *
* @param zFile_name The name of the module. * @param zFile_name The name of the module.
* *
* @return A module instance if the module could be loaded and it was of * @return A module instance if the module could be loaded and it was of
* the expected type. * the expected type.
*/ */
template<class T> template<class T, class API>
class SpecificModule : public Module class SpecificModule : public Module
{ {
public: public:
typedef SpecificModule<T, API> Base;
static std::auto_ptr<T> load(const char* zFile_name) static std::auto_ptr<T> load(const char* zFile_name)
{ {
std::auto_ptr<T> sT; std::auto_ptr<T> sT;
void* pApi = Module::load(zFile_name, T::zName); const MXS_MODULE* pModule = Module::get(zFile_name, T::zName);
if (pApi) if (pModule)
{ {
sT.reset(new T(static_cast<typename T::type_t*>(pApi))); sT.reset(new T(pModule));
} }
return sT; return sT;
} }
protected: protected:
SpecificModule() SpecificModule(const MXS_MODULE* pModule)
: Module(pModule)
, m_pApi(static_cast<API*>(pModule->module_object))
{ {
} }
API* m_pApi;
}; };
} }

View File

@ -24,25 +24,19 @@ namespace maxscale
* A QueryClassfierModule instance is an abstraction for a query * A QueryClassfierModule instance is an abstraction for a query
* classifier module. * classifier module.
*/ */
class QueryClassifierModule : public SpecificModule<QueryClassifierModule> class QueryClassifierModule : public SpecificModule<QueryClassifierModule, QUERY_CLASSIFIER>
{ {
QueryClassifierModule(const QueryClassifierModule&); QueryClassifierModule(const QueryClassifierModule&);
QueryClassifierModule& operator = (const QueryClassifierModule&); QueryClassifierModule& operator = (const QueryClassifierModule&);
public: public:
static const char* zName; /*< The name describing the module type. */ static const char* zName; /*< The name describing the module type. */
typedef QUERY_CLASSIFIER type_t; /*< The type of the module object. */
private: private:
friend class SpecificModule<QueryClassifierModule>; QueryClassifierModule(const MXS_MODULE* pModule)
: Base(pModule)
QueryClassifierModule(QUERY_CLASSIFIER* pApi)
: m_pApi(pApi)
{ {
} }
private:
QUERY_CLASSIFIER* m_pApi;
}; };
} }

View File

@ -23,6 +23,12 @@ void* Module::load(const char* zName, const char* zType)
return load_module(zName, zType); return load_module(zName, zType);
} }
//static
const MXS_MODULE* Module::get(const char* zName, const char* zType)
{
return get_module(zName, zType);
}
//static //static
bool Module::process_init() bool Module::process_init()
{ {