5 #ifndef CVMFS_UTIL_PLUGIN_H_
6 #define CVMFS_UTIL_PLUGIN_H_
16 #ifdef CVMFS_NAMESPACE_GUARD
17 namespace CVMFS_NAMESPACE_GUARD {
32 template<
class AbstractProductT,
typename ParameterT,
typename InfoT>
38 virtual bool WillHandle(
const ParameterT ¶m)
const = 0;
39 virtual AbstractProductT *Construct(
const ParameterT ¶m)
const = 0;
40 virtual InfoT Introspect()
const = 0;
57 template<
class ConcreteProductT,
class AbstractProductT,
typename ParameterT,
63 return ConcreteProductT::WillHandle(param);
65 inline AbstractProductT *
Construct(
const ParameterT ¶m)
const {
66 AbstractProductT *product =
new ConcreteProductT(param);
78 template<
class ConcreteProductT,
class AbstractProductT,
typename ParameterT,
83 inline InfoT
Introspect()
const {
return ConcreteProductT::GetInfo(); }
90 template<
class ConcreteProductT,
class AbstractProductT,
typename ParameterT>
161 template<
class AbstractProductT,
typename ParameterT,
typename InfoT>
170 static AbstractProductT *
Construct(
const ParameterT ¶m) {
171 LazilyRegisterPlugins();
175 typename RegisteredPlugins::const_iterator i = registered_plugins_.begin();
176 typename RegisteredPlugins::const_iterator iend = registered_plugins_.end();
177 for (; i != iend; ++i) {
178 if ((*i)->WillHandle(param)) {
180 AbstractProductT *product = (*i)->Construct(param);
181 if (!product->Initialize()) {
203 if (atomic_read32(&needs_init_)) {
205 if (atomic_read32(&needs_init_)) {
206 AbstractProductT::RegisterPlugins();
207 atomic_dec32(&needs_init_);
211 assert(!registered_plugins_.empty());
217 friend class PolymorphicConstructionUnittestAdapter;
230 template<
class ConcreteProductT>
232 registered_plugins_.push_back(
252 registered_plugins_.clear();
272 template<
class AbstractProductT,
typename ParameterT,
typename InfoT =
void>
284 introspection_data.reserve(T::registered_plugins_.
size());
287 T::LazilyRegisterPlugins();
288 typename RegisteredPlugins::const_iterator i = plugins.begin();
289 typename RegisteredPlugins::const_iterator iend = plugins.end();
290 for (; i != iend; ++i) {
291 introspection_data.push_back((*i)->Introspect());
294 return introspection_data;
302 template<
class AbstractProductT,
typename ParameterT>
308 template<
class AbstractProductT,
typename ParameterT,
typename InfoT>
310 InfoT>::needs_init_ = 1;
312 template<
class AbstractProductT,
typename ParameterT,
typename InfoT>
315 InfoT>::init_mutex_ = PTHREAD_MUTEX_INITIALIZER;
319 template<
class AbstractProductT,
typename ParameterT,
typename InfoT>
321 InfoT>::RegisteredPlugins
323 InfoT>::registered_plugins_;
326 #ifdef CVMFS_NAMESPACE_GUARD
330 #endif // CVMFS_UTIL_PLUGIN_H_
virtual bool Initialize()
static IntrospectionData Introspect()
virtual ~PolymorphicConstructionImpl()
virtual ~AbstractFactory()
AbstractFactory< AbstractProductT, ParameterT, InfoT > Factory
assert((mem||(size==0))&&"Out Of Memory")
static RegisteredPlugins registered_plugins_
static AbstractProductT * Construct(const ParameterT ¶m)
std::vector< InfoT > IntrospectionData
static void UnregisterAllPlugins()
PolymorphicConstructionImpl< AbstractProductT, ParameterT, InfoT > T
static atomic_int32 needs_init_
bool WillHandle(const ParameterT ¶m) const
static void LazilyRegisterPlugins()
T::RegisteredPlugins RegisteredPlugins
static void RegisterPlugin()
static pthread_mutex_t init_mutex_
std::vector< Factory * > RegisteredPlugins
AbstractProductT * Construct(const ParameterT ¶m) const