The Gaudi Framework  v41r0 (bdbe7744)
Loading...
Searching...
No Matches
Gaudi::PluginService::v1::Details::Registry Class Reference

In-memory database of the loaded factories. More...

#include </builds/gaudi/Gaudi/GaudiPluginService/include/Gaudi/Details/PluginServiceDetailsV1.h>

Collaboration diagram for Gaudi::PluginService::v1::Details::Registry:

Classes

struct  FactoryInfo

Public Types

typedef std::string KeyType
typedef std::map< KeyType, std::string > Properties
 Type used for the properties implementation.
typedef std::map< KeyType, FactoryInfo > FactoryMap
 Type used for the database implementation.

Public Member Functions

template<typename F, typename T, typename I>
FactoryInfo & add (const I &id, typename F::FuncType ptr)
 Add a factory to the database.
void * get (const std::string &id, const std::string &type) const
 Retrieve the factory for the given id.
const FactoryInfo & getInfo (const std::string &id) const
 Retrieve the FactoryInfo object for an id.
Registry & addProperty (const std::string &id, const std::string &k, const std::string &v)
 Add a property to an already existing FactoryInfo object (via its id.).
std::set< KeyType > loadedFactoryNames () const
 Return a list of all the known and loaded factories.
const FactoryMap & factories () const
 Return the known factories (loading the list if not yet done).

Static Public Member Functions

static Registry & instance ()
 Retrieve the singleton instance of Registry.

Private Member Functions

 Registry ()
 Private constructor for the singleton pattern.
 Registry (const Registry &)
 Private copy constructor for the singleton pattern.
FactoryInfo & add (const std::string &id, void *factory, const std::string &type, const std::string &rtype, const std::string &className, const Properties &props=Properties())
 Add a factory to the database.
FactoryMap & factories ()
 Return the known factories (loading the list if not yet done).
void initialize ()
 Initialize the registry loading the list of factories from the .component files in the library search path.

Private Attributes

bool m_initialized
 Flag recording if the registry has been initialized or not.
FactoryMap m_factories
 Internal storage for factories.
std::recursive_mutex m_mutex
 Mutex used to control concurrent access to the internal data.

Detailed Description

In-memory database of the loaded factories.

Definition at line 83 of file PluginServiceDetailsV1.h.

Member Typedef Documentation

◆ FactoryMap

Type used for the database implementation.

Definition at line 114 of file PluginServiceDetailsV1.h.

◆ KeyType

Definition at line 85 of file PluginServiceDetailsV1.h.

◆ Properties

Type used for the properties implementation.

Definition at line 88 of file PluginServiceDetailsV1.h.

Constructor & Destructor Documentation

◆ Registry() [1/2]

Gaudi::PluginService::v2::Details::Registry::Registry ( )
private

Private constructor for the singleton pattern.

At construction time, the internal database of known factories is filled with the name of the libraries containing them, using the ".components" files in the LD_LIBRARY_PATH.

Definition at line 137 of file PluginServiceV1.cpp.

137: m_initialized( false ) {}
bool m_initialized
Flag recording if the registry has been initialized or not.

◆ Registry() [2/2]

Gaudi::PluginService::v1::Details::Registry::Registry ( const Registry & )
inlineprivate

Private copy constructor for the singleton pattern.

Definition at line 159 of file PluginServiceDetailsV1.h.

159: m_initialized( false ) {}

Member Function Documentation

◆ add() [1/2]

template<typename F, typename T, typename I>
FactoryInfo & Gaudi::PluginService::v1::Details::Registry::add ( const I & id,
typename F::FuncType ptr )
inline

Add a factory to the database.

Definition at line 121 of file PluginServiceDetailsV1.h.

121 {
122 union {
123 typename F::FuncType src;
124 void* dst;
125 } p2p;
126 p2p.src = ptr;
127 std::ostringstream o;
128 o << id;
129 return add( o.str(), p2p.dst, typeid( typename F::FuncType ).name(),
130 typeid( typename F::ReturnType ).name(), demangle<T>() );
131 }
FactoryInfo & add(const I &id, typename F::FuncType ptr)
Add a factory to the database.
std::string demangle()
Return a canonical name for the template argument.

◆ add() [2/2]

Registry::FactoryInfo & Gaudi::PluginService::v1::Details::Registry::add ( const std::string & id,
void * factory,
const std::string & type,
const std::string & rtype,
const std::string & className,
const Properties & props = Properties() )
private

Add a factory to the database.

Definition at line 208 of file PluginServiceV1.cpp.

210 {
211 auto _guard = std::scoped_lock{ m_mutex };
212 FactoryMap& facts = factories();
213 auto entry = facts.find( id );
214 if ( entry == facts.end() ) {
215 // this factory was not known yet
216 entry = facts.emplace( id, FactoryInfo( "unknown", factory, type, rtype, className, props ) ).first;
217 } else {
218 // do not replace an existing factory with a new one
219 if ( !entry->second.ptr ) entry->second.ptr = factory;
220 factoryInfoSetHelper( entry->second.type, type, "type", id );
221 factoryInfoSetHelper( entry->second.rtype, rtype, "return type", id );
222 factoryInfoSetHelper( entry->second.className, className, "class", id );
223 }
224#ifdef GAUDI_REFLEX_COMPONENT_ALIASES
225 // add an alias for the factory using the Reflex convention
226 std::string old_name = old_style_name( id );
227 if ( id != old_name )
228 add( old_name, factory, type, rtype, className, props ).properties["ReflexName"] = "true";
229#endif
230 return entry->second;
231 }
std::map< KeyType, FactoryInfo > FactoryMap
Type used for the database implementation.
std::recursive_mutex m_mutex
Mutex used to control concurrent access to the internal data.
const FactoryMap & factories() const
Return the known factories (loading the list if not yet done).

◆ addProperty()

Registry & Gaudi::PluginService::v2::Details::Registry::addProperty ( const std::string & id,
const std::string & k,
const std::string & v )

Add a property to an already existing FactoryInfo object (via its id.).

Definition at line 270 of file PluginServiceV1.cpp.

270 {
271 auto _guard = std::scoped_lock{ m_mutex };
272 FactoryMap& facts = factories();
273 auto f = facts.find( id );
274 if ( f != facts.end() ) f->second.properties[k] = v;
275 return *this;
276 }

◆ factories() [1/2]

Registry::FactoryMap & Gaudi::PluginService::v2::Details::Registry::factories ( )
inlineprivate

Return the known factories (loading the list if not yet done).

Definition at line 166 of file PluginServiceDetailsV1.h.

166 {
167 if ( !m_initialized ) initialize();
168 return m_factories;
169 }
void initialize()
Initialize the registry loading the list of factories from the .component files in the library search...
FactoryMap m_factories
Internal storage for factories.

◆ factories() [2/2]

const Registry::FactoryMap & Gaudi::PluginService::v2::Details::Registry::factories ( ) const
inline

Return the known factories (loading the list if not yet done).

Definition at line 146 of file PluginServiceDetailsV1.h.

146 {
147 if ( !m_initialized ) const_cast<Registry*>( this )->initialize();
148 return m_factories;
149 }
Registry()
Private constructor for the singleton pattern.

◆ get()

void * Gaudi::PluginService::v1::Details::Registry::get ( const std::string & id,
const std::string & type ) const

Retrieve the factory for the given id.

Definition at line 233 of file PluginServiceV1.cpp.

233 {
234 auto _guard = std::scoped_lock{ m_mutex };
235 const FactoryMap& facts = factories();
236 auto f = facts.find( id );
237 if ( f != facts.end() ) {
238#ifdef GAUDI_REFLEX_COMPONENT_ALIASES
239 const Properties& props = f->second.properties;
240 if ( props.find( "ReflexName" ) != props.end() )
241 logger().warning( "requesting factory via old name '" + id +
242 "'"
243 "use '" +
244 f->second.className + "' instead" );
245#endif
246 if ( !f->second.ptr ) {
247 if ( !dlopen( f->second.library.c_str(), RTLD_LAZY | RTLD_GLOBAL ) ) {
248 logger().warning( "cannot load " + f->second.library + " for factory " + id );
249 char* dlmsg = dlerror();
250 if ( dlmsg ) logger().warning( dlmsg );
251 return nullptr;
252 }
253 f = facts.find( id ); // ensure that the iterator is valid
254 }
255 if ( f->second.type == type ) return f->second.ptr;
256 logger().warning( "found factory " + id + ", but of wrong type: " + demangle( f->second.type ) +
257 " instead of " + demangle( type ) );
258 }
259 return nullptr; // factory not found
260 }
std::map< KeyType, std::string > Properties
Type used for the properties implementation.
GAUDIPS_API Logger & logger()
Return the current logger instance.

◆ getInfo()

const Registry::FactoryInfo & Gaudi::PluginService::v2::Details::Registry::getInfo ( const std::string & id) const

Retrieve the FactoryInfo object for an id.

Definition at line 262 of file PluginServiceV1.cpp.

262 {
263 auto _guard = std::scoped_lock{ m_mutex };
264 static const FactoryInfo unknown( "unknown" );
265 const FactoryMap& facts = factories();
266 auto f = facts.find( id );
267 return ( f != facts.end() ) ? f->second : unknown;
268 }

◆ initialize()

void Gaudi::PluginService::v2::Details::Registry::initialize ( )
private

Initialize the registry loading the list of factories from the .component files in the library search path.

Definition at line 139 of file PluginServiceV1.cpp.

139 {
140 auto _guard = std::scoped_lock{ m_mutex };
141 if ( m_initialized ) return;
142 m_initialized = true;
143
144 for ( const auto& dirName : v2::Details::getPluginSearchPath() ) {
145 logger().debug( std::string( " looking into " ) + dirName );
146 // look for files called "*.components" in the directory
147 DIR* dir = opendir( dirName.c_str() );
148 if ( dir ) {
149 struct dirent* entry;
150 while ( ( entry = readdir( dir ) ) ) {
151 std::string name( entry->d_name );
152 // check if the file name ends with ".components"
153 std::string::size_type extpos = name.find( ".components" );
154 if ( ( extpos != std::string::npos ) && ( ( extpos + 11 ) == name.size() ) ) {
155 std::string fullPath = ( dirName + '/' + name );
156 { // check if it is a regular file
157 struct stat buf;
158 stat( fullPath.c_str(), &buf );
159 if ( !S_ISREG( buf.st_mode ) ) continue;
160 }
161 // read the file
162 logger().debug( std::string( " reading " ) + name );
163 std::ifstream factories{ fullPath };
164 std::string line;
165 int factoriesCount = 0;
166 int lineCount = 0;
167 while ( !factories.eof() ) {
168 ++lineCount;
169 std::getline( factories, line );
170 trim( line );
171 // skip empty lines and lines starting with '#'
172 if ( line.empty() || line[0] == '#' ) continue;
173 // only accept "v1" factories
174 if ( line.substr( 0, 4 ) == "v1::" )
175 line = line.substr( 4 );
176 else
177 continue;
178 // look for the separator
179 auto pos = line.find( ':' );
180 if ( pos == std::string::npos ) {
181 logger().warning( "failed to parse line " + fullPath + ':' + std::to_string( lineCount ) );
182 continue;
183 }
184 const std::string lib( line, 0, pos );
185 const std::string fact( line, pos + 1 );
186 m_factories.emplace( fact, FactoryInfo( lib ) );
187#ifdef GAUDI_REFLEX_COMPONENT_ALIASES
188 // add an alias for the factory using the Reflex convention
189 std::string old_name = old_style_name( fact );
190 if ( fact != old_name ) {
191 FactoryInfo old_info( lib );
192 old_info.properties["ReflexName"] = "true";
193 m_factories.emplace( old_name, old_info );
194 }
195#endif
196 ++factoriesCount;
197 }
198 if ( logger().level() <= Logger::Debug ) {
199 logger().debug( " found " + std::to_string( factoriesCount ) + " factories" );
200 }
201 }
202 }
203 closedir( dir );
204 }
205 }
206 }
const std::vector< std::string > & getPluginSearchPath()

◆ instance()

Registry & Gaudi::PluginService::v2::Details::Registry::instance ( )
static

Retrieve the singleton instance of Registry.

Definition at line 131 of file PluginServiceV1.cpp.

131 {
132 auto _guard = std::scoped_lock{ ::registrySingletonMutex };
133 static Registry r;
134 return r;
135 }

◆ loadedFactoryNames()

std::set< Registry::KeyType > Gaudi::PluginService::v2::Details::Registry::loadedFactoryNames ( ) const

Return a list of all the known and loaded factories.

Definition at line 278 of file PluginServiceV1.cpp.

278 {
279 auto _guard = std::scoped_lock{ m_mutex };
280 std::set<KeyType> l;
281 for ( const auto& f : factories() ) {
282 if ( f.second.ptr ) l.insert( f.first );
283 }
284 return l;
285 }
dict l
Definition gaudirun.py:591

Member Data Documentation

◆ m_factories

FactoryMap Gaudi::PluginService::v1::Details::Registry::m_factories
private

Internal storage for factories.

Definition at line 179 of file PluginServiceDetailsV1.h.

◆ m_initialized

bool Gaudi::PluginService::v1::Details::Registry::m_initialized
private

Flag recording if the registry has been initialized or not.

Definition at line 176 of file PluginServiceDetailsV1.h.

◆ m_mutex

std::recursive_mutex Gaudi::PluginService::v1::Details::Registry::m_mutex
mutableprivate

Mutex used to control concurrent access to the internal data.

Definition at line 182 of file PluginServiceDetailsV1.h.


The documentation for this class was generated from the following files: