ATLAS Offline Software
Loading...
Searching...
No Matches
ClassIDSvc Class Reference

a service to manage and verify CLID assignments in athena. More...

#include <ClassIDSvc.h>

Inheritance diagram for ClassIDSvc:
Collaboration diagram for ClassIDSvc:

Public Member Functions

IClassIDSvc interfaces.
virtual CLID nextAvailableID () const override
 get next available CLID
virtual bool isIDInUse (const CLID &id) const override
 check if id is used
virtual bool isNameInUse (const std::string &name) const override
 check if id is used
virtual StatusCode getTypeNameOfID (const CLID &id, std::string &typeName) const override
 get type name associated with clID (if any)
virtual StatusCode getTypeInfoNameOfID (const CLID &id, std::string &typeInfoName) const override
 get user assigned type-info name associated with clID
virtual StatusCode getIDOfTypeName (const std::string &typeName, CLID &id) const override
 get id associated with type name (if any)
virtual StatusCode getIDOfTypeInfoName (const std::string &typeInfoName, CLID &id) const override
 get id associated with type-info name (if any)
virtual StatusCode setTypeForID (const CLID &id, const std::string &typeName, const std::string &typeInfoName="") override
 associate type name, package info and type-info name with clID
Debugging methods.
void dump () const
 dump to MsgStream contents of in memory DB

Private Types

typedef std::pair< std::string, std::string > TypeName
typedef std::unordered_map< CLID, TypeNameCLIDMap
typedef std::unordered_map< std::string, CLIDNameMap

Properties

typedef std::mutex mutex_t
typedef std::lock_guard< mutex_tlock_t
Gaudi::Property< std::vector< std::string > > m_DBFiles
Gaudi::Property< std::string > m_outputFileName
CLIDMap m_clidMap
NameMap m_nameMap
NameMap m_tiNameMap
DirSearchPath m_clidDBPath
 The path is which clid db files are to be searched (DATAPATH)
mutex_t m_mutex

Gaudi methods.

virtual StatusCode initialize () override
 Gaudi Service Implementation.
virtual StatusCode reinitialize () override
virtual StatusCode finalize () override
 dump CLIDmap to outputFileName;
void handle (const Incident &inc) override
 implement IIncidentListener
 ClassIDSvc (const std::string &name, ISvcLocator *svc)
 Standard Constructor.
std::vector< CLIDsortedIDs () const
 Return all registered IDs in sorted order.
StatusCode fillDB ()
 get clids from CLIDDB and from registry entries
bool processCLIDDB (const std::string &fileName)
 load clid/names from a "db" file
bool getRegistryEntries (const std::string &moduleName)
 load clid/names from a DLL registry
StatusCode uncheckedSetTypePackageForID (const CLID &id, const std::string &typeName, const std::string &typeInfoName)
 associate type name with clID w/o checking CLID range
bool maybeRescan () const
 Test to see if anything new has been added to the registry.

Detailed Description

a service to manage and verify CLID assignments in athena.

(clid, class_name) entries are loaded at init from the list of files specifies in "CLIDDBFiles", and from the CLID_Registry of every library. Optionally the resulting m_clidMap can be dumped to "OutputFileName" at finalize time.

Definition at line 36 of file ClassIDSvc.h.

Member Typedef Documentation

◆ CLIDMap

typedef std::unordered_map<CLID, TypeName> ClassIDSvc::CLIDMap
private

Definition at line 40 of file ClassIDSvc.h.

◆ lock_t

typedef std::lock_guard<mutex_t> ClassIDSvc::lock_t
private

Definition at line 133 of file ClassIDSvc.h.

◆ mutex_t

typedef std::mutex ClassIDSvc::mutex_t
private

Definition at line 132 of file ClassIDSvc.h.

◆ NameMap

typedef std::unordered_map<std::string, CLID> ClassIDSvc::NameMap
private

Definition at line 41 of file ClassIDSvc.h.

◆ TypeName

typedef std::pair<std::string, std::string> ClassIDSvc::TypeName
private

Definition at line 39 of file ClassIDSvc.h.

Constructor & Destructor Documentation

◆ ClassIDSvc()

ClassIDSvc::ClassIDSvc ( const std::string & name,
ISvcLocator * svc )

Standard Constructor.

Definition at line 276 of file ClassIDSvc.cxx.

277 : base_class(name,svc),
278 m_clidDBPath(System::getEnv("DATAPATH"))
279{
280}
DirSearchPath m_clidDBPath
The path is which clid db files are to be searched (DATAPATH)
Definition ClassIDSvc.h:129

Member Function Documentation

◆ dump()

void ClassIDSvc::dump ( ) const

dump to MsgStream contents of in memory DB

Definition at line 198 of file ClassIDSvc.cxx.

199{
200 lock_t lock (m_mutex);
201 ATH_MSG_INFO( "dump: in memory" );
202
203 for (CLID clid : sortedIDs()) {
204 auto it = m_clidMap.find (clid);
205 if (it == m_clidMap.end()) {
206 ATH_MSG_INFO( "CLID: "<< clid << " - type name: NOT FOUND" );
207 }
208 else {
209 ATH_MSG_INFO( "CLID: "<< clid << " - type name: " << it->second.first );
210 }
211 }
212 ATH_MSG_INFO( "------------------------------" );
213}
#define ATH_MSG_INFO(x)
uint32_t CLID
The Class ID type.
CLIDMap m_clidMap
Definition ClassIDSvc.h:124
std::vector< CLID > sortedIDs() const
Return all registered IDs in sorted order.
std::lock_guard< mutex_t > lock_t
Definition ClassIDSvc.h:133
mutex_t m_mutex
Definition ClassIDSvc.h:134

◆ fillDB()

StatusCode ClassIDSvc::fillDB ( )
private

get clids from CLIDDB and from registry entries

Process the various clid dbs according to user's request.

Definition at line 298 of file ClassIDSvc.cxx.

298 {
299 bool allOK(true);
300 for (const std::string& DBFile : m_DBFiles) {
301 DirSearchPath::path clidDB(DBFile);
302
303 if (clidDB.is_absolute()) {
304 allOK = processCLIDDB(clidDB.string());
305 } else {
306 std::list<DirSearchPath::path> paths(m_clidDBPath.find_all(clidDB));
307 if (paths.empty()) {
308 ATH_MSG_DEBUG( "Could not resolve clid DB path " << clidDB
309 << " using DATAPATH. Skipping it." );
310 } else {
311 for (const auto& p : paths) {
312 allOK &= processCLIDDB(p.string());
313 }
314 }
315 }
316 }
317 return StatusCode(allOK);
318}
#define ATH_MSG_DEBUG(x)
Gaudi::Property< std::vector< std::string > > m_DBFiles
Definition ClassIDSvc.h:117
bool processCLIDDB(const std::string &fileName)
load clid/names from a "db" file
::StatusCode StatusCode
StatusCode definition for legacy code.

◆ finalize()

StatusCode ClassIDSvc::finalize ( )
overridevirtual

dump CLIDmap to outputFileName;

Definition at line 245 of file ClassIDSvc.cxx.

246{
247 if (m_outputFileName != "NULL") {
248 std::ofstream outfile( m_outputFileName );
249 if ( !outfile ) {
250 ATH_MSG_ERROR( "unable to open output CLIDDB file: " << m_outputFileName );
251 return StatusCode::RECOVERABLE;
252 } else {
253 for (CLID clid : sortedIDs()) {
254 const std::string& typeName = m_clidMap[clid].first;
255 const std::string& tiName = m_clidMap[clid].second;
256 outfile << clid << "; " << typeName << "; " << tiName << std::endl;
257 }
258 ATH_MSG_INFO( "finalize: wrote " << m_clidMap.size() <<
259 " entries to output CLIDDB file: " << m_outputFileName );
260 }
261 }
262 return Service::finalize();
263}
#define ATH_MSG_ERROR(x)
Gaudi::Property< std::string > m_outputFileName
Definition ClassIDSvc.h:121

◆ getIDOfTypeInfoName()

StatusCode ClassIDSvc::getIDOfTypeInfoName ( const std::string & typeInfoName,
CLID & id ) const
overridevirtual

get id associated with type-info name (if any)

Definition at line 162 of file ClassIDSvc.cxx.

164{
165 lock_t lock (m_mutex);
166 maybeRescan();
167 NameMap::const_iterator iID = m_tiNameMap.find(typeInfoName);
168 if (iID != m_tiNameMap.end()) {
169 id = iID->second;
170 ATH_CONST_MSG_VERBOSE( "getIDOfTypeInfoName(" << typeInfoName << ") CLID is " << id );
171 return StatusCode::SUCCESS;
172 }
173 else {
174 ATH_CONST_MSG_VERBOSE( "getIDOfTypeInfoName(" << typeInfoName << ") no associated CLID found" );
175 return StatusCode::FAILURE;
176 }
177}
#define ATH_CONST_MSG_VERBOSE(x)
NameMap m_tiNameMap
Definition ClassIDSvc.h:126
bool maybeRescan() const
Test to see if anything new has been added to the registry.

◆ getIDOfTypeName()

StatusCode ClassIDSvc::getIDOfTypeName ( const std::string & typeName,
CLID & id ) const
overridevirtual

get id associated with type name (if any)

Definition at line 138 of file ClassIDSvc.cxx.

139{
140 lock_t lock (m_mutex);
141 maybeRescan();
142
143 NameMap::const_iterator iID = m_nameMap.find(typeName);
144 if (iID != m_nameMap.end()) {
145 id = iID->second;
146 ATH_CONST_MSG_VERBOSE( "getIDOfTypeName(" << typeName << ") CLID is " << id );
147 return StatusCode::SUCCESS;
148 }
149 else if (tryNumeric (typeName, id)) {
150 ATH_CONST_MSG_VERBOSE( "getIDOfTypeName(" << typeName << ") is a numeric CLID" );
151 return StatusCode::SUCCESS;
152 }
153 else {
154 ATH_CONST_MSG_VERBOSE( "getIDOfTypeName(" << typeName << ") no associated CLID found" );
155 return StatusCode::FAILURE;
156 }
157}
NameMap m_nameMap
Definition ClassIDSvc.h:125

◆ getRegistryEntries()

bool ClassIDSvc::getRegistryEntries ( const std::string & moduleName)
private

load clid/names from a DLL registry

Definition at line 366 of file ClassIDSvc.cxx.

367{
368 //not only this is fast, but is necessary to prevent recursion
369 if (!CLIDRegistry::hasNewEntries()) return true;
370
371 bool allOK(true);
372 size_t newEntries(0);
373 //to speed up processing we only take entries added to CLIDRegistry
374 //since last call (thanks Niels!)
375 for (const auto& [clid, typeName, typeInfoName] : CLIDRegistry::newEntries()) {
376 ATH_MSG_VERBOSE( "reading [" << clid << ", " << typeName << ", " << typeInfoName << "]" );
377 if (uncheckedSetTypePackageForID(clid, typeName, typeInfoName)) {
378 ++newEntries;
379 }
380 else {
381 allOK = false;
382 }
383 }
384
385 if (allOK) {
386 ATH_MSG_INFO( "getRegistryEntries: read " << newEntries
387 << " CLIDRegistry entries for module " << moduleName );
388 } else {
389 ATH_MSG_ERROR("getRegistryEntries: can not read CLIDRegistry entries for module "
390 << moduleName );
391 }
392
393 return allOK;
394}
#define ATH_MSG_VERBOSE(x)
static bool hasNewEntries()
registry accessors (used by ClassIDSvc)
static CLIDVector_t newEntries()
returns an iterator range over the entries added since last time newEntries was called
StatusCode uncheckedSetTypePackageForID(const CLID &id, const std::string &typeName, const std::string &typeInfoName)
associate type name with clID w/o checking CLID range

◆ getTypeInfoNameOfID()

StatusCode ClassIDSvc::getTypeInfoNameOfID ( const CLID & id,
std::string & typeInfoName ) const
overridevirtual

get user assigned type-info name associated with clID

get type name associated with clID (if any)

Definition at line 116 of file ClassIDSvc.cxx.

117{
118 lock_t lock (m_mutex);
119 maybeRescan();
120
121 CLIDMap::const_iterator iID = m_clidMap.find(id);
122 if (iID != m_clidMap.end()) {
123 typeInfoName = iID->second.second;
124 ATH_CONST_MSG_VERBOSE( "getTypeInfoNameOfID(" << id <<
125 ") type-info name is " << typeInfoName );
126 return StatusCode::SUCCESS;
127 }
128 else {
129 ATH_CONST_MSG_VERBOSE( "getTypeInfoNameOfID(" << id <<
130 ") no associated type-info name found" );
131 return StatusCode::FAILURE;
132 }
133}

◆ getTypeNameOfID()

StatusCode ClassIDSvc::getTypeNameOfID ( const CLID & id,
std::string & typeName ) const
overridevirtual

get type name associated with clID (if any)

Definition at line 96 of file ClassIDSvc.cxx.

97{
98 lock_t lock (m_mutex);
100
101 CLIDMap::const_iterator iID = m_clidMap.find(id);
102 if (iID != m_clidMap.end()) {
103 typeName = iID->second.first;
104 ATH_CONST_MSG_VERBOSE( "getTypeNameOfID(" << id << ") type name is " << typeName );
105 return StatusCode::SUCCESS;
106 }
107 else {
108 ATH_CONST_MSG_VERBOSE( "getTypeNameOfID(" << id << ") no associated type name found" );
109 return StatusCode::FAILURE;
110 }
111}

◆ handle()

void ClassIDSvc::handle ( const Incident & inc)
override

implement IIncidentListener

Definition at line 266 of file ClassIDSvc.cxx.

267{
268 lock_t lock (m_mutex);
269 const ModuleLoadedIncident& modInc(dynamic_cast<const ModuleLoadedIncident&>(inc));
270
271 getRegistryEntries(modInc.module());
272}
bool getRegistryEntries(const std::string &moduleName)
load clid/names from a DLL registry

◆ initialize()

StatusCode ClassIDSvc::initialize ( )
overridevirtual

Gaudi Service Implementation.

Definition at line 217 of file ClassIDSvc.cxx.

218{
219 ATH_MSG_VERBOSE( "Initializing " << name() ) ;
220
221 CHECK( Service::initialize() );
222
223 // set up the incident service:
224 ServiceHandle<IIncidentSvc> pIncSvc ("IncidentSvc", name());
225 CHECK( pIncSvc.retrieve() );
226
227 pIncSvc->addListener(this, ModuleLoadedIncident::TYPE(), /*priority*/ 100);
228 pIncSvc->release();
229
230 CHECK( maybeRescan() ); // calls fillDB() if not already done
231
232 return StatusCode::SUCCESS;
233}
#define CHECK(...)
Evaluate an expression and check for errors.

◆ isIDInUse()

bool ClassIDSvc::isIDInUse ( const CLID & id) const
overridevirtual

check if id is used

Definition at line 79 of file ClassIDSvc.cxx.

79 {
80 lock_t lock (m_mutex);
82 return m_clidMap.find(id) != m_clidMap.end();
83}

◆ isNameInUse()

bool ClassIDSvc::isNameInUse ( const std::string & name) const
overridevirtual

check if id is used

Definition at line 87 of file ClassIDSvc.cxx.

87 {
88 lock_t lock (m_mutex);
90 return m_nameMap.find(name) != m_nameMap.end();
91}

◆ maybeRescan()

bool ClassIDSvc::maybeRescan ( ) const
private

Test to see if anything new has been added to the registry.

Definition at line 453 of file ClassIDSvc.cxx.

454{
455 // thread-safe because calls are protected by mutex or during initialize
456 ClassIDSvc* nc ATLAS_THREAD_SAFE = const_cast<ClassIDSvc*>(this);
457
458 // read CLID database in case initialize() was not called yet (ATR-23634)
459 [[maybe_unused]] static bool fillDB ATLAS_THREAD_SAFE = nc->fillDB().isSuccess();
460
461 // make sure registry is up-to-date
462 bool status = nc->getRegistryEntries ("ALL");
463
464 return status && fillDB;
465}
#define ATLAS_THREAD_SAFE
StatusCode fillDB()
get clids from CLIDDB and from registry entries
ClassIDSvc(const std::string &name, ISvcLocator *svc)
Standard Constructor.
status
Definition merge.py:16

◆ nextAvailableID()

CLID ClassIDSvc::nextAvailableID ( ) const
overridevirtual

get next available CLID

Exceptions
std::runtime_errorif no CLID can be allocated virtual CLID nextAvailableID() const;
std::runtime_errorif no CLID can be allocated

Definition at line 60 of file ClassIDSvc.cxx.

60 {
61 lock_t lock (m_mutex);
64 while (valid <= CLIDdetail::MAXCLID &&
65 m_clidMap.find(valid) != m_clidMap.end())
66 {
67 ++valid;
68 }
69
70 if (valid > CLIDdetail::MAXCLID) {
71 throw std::runtime_error("ClassIDSvc::nextAvailableID: none in range");
72 }
73
74 return valid;
75}
const unsigned long MINCLID
const unsigned long MAXCLID
2**31 - 1
list valid
Definition calibdata.py:44

◆ processCLIDDB()

bool ClassIDSvc::processCLIDDB ( const std::string & fileName)
private

load clid/names from a "db" file

Definition at line 322 of file ClassIDSvc.cxx.

323{
324 std::ifstream ifile(fileName);
325 if (!ifile) {
326 ATH_MSG_WARNING( "processCLIDDB: unable to open " << fileName );
327 return true;
328 }
329
330 bool allOK(true);
331 unsigned int newEntries(0);
332 std::string line;
333 // Format: CLID;typeName[;typeInfoName]
334 while (allOK && std::getline(ifile, line)) {
335 std::vector<std::string> columns;
336 boost::split(columns, line, boost::is_any_of(";"));
337 long id(-1);
338 if (columns.size()>=2) {
339 boost::trim(columns[0]);
340 try {
341 id = std::stol(columns[0]);
342 } catch (const std::logic_error& e) {
343 ATH_MSG_ERROR( "processCLIDDB: Can't cast ["<< columns[0] << "] to long (clid): " << e.what() );
344 allOK = false;
345 }
346
347 if (uncheckedSetTypePackageForID(id, columns[1],
348 columns.size()>2 ? columns[2] : "")) {
349 ++newEntries;
350 }
351 }
352 }
353
354 if (!allOK) {
355 ATH_MSG_ERROR( "processCLIDDB: processing record '" << line
356 << "' from CLIDDB file: " << fileName );
357 } else {
358 ATH_MSG_DEBUG( "processCLIDDB: read " << newEntries <<
359 " entries from CLIDDB file: " << fileName );
360 }
361
362 return allOK;
363}
#define ATH_MSG_WARNING(x)

◆ reinitialize()

StatusCode ClassIDSvc::reinitialize ( )
overridevirtual

Definition at line 237 of file ClassIDSvc.cxx.

237 {
238 ATH_MSG_INFO( "RE-initializing " << name() ) ;
239 CHECK( fillDB() );
240 return StatusCode::SUCCESS;
241}

◆ setTypeForID()

StatusCode ClassIDSvc::setTypeForID ( const CLID & id,
const std::string & typeName,
const std::string & typeInfoName = "" )
overridevirtual

associate type name, package info and type-info name with clID

associate type name with clID

Definition at line 182 of file ClassIDSvc.cxx.

185{
186 lock_t lock (m_mutex);
187 if (id < CLIDdetail::MINCLID || id > CLIDdetail::MAXCLID) {
188 ATH_MSG_ERROR( "setTypeNameForID: input id " << id
189 << " is out of allowed range " << CLIDdetail::MINCLID
190 << " : " << CLIDdetail::MAXCLID );
191 return StatusCode::FAILURE;
192 }
193 return uncheckedSetTypePackageForID(id, typeName, typeInfoName);
194}

◆ sortedIDs()

std::vector< CLID > ClassIDSvc::sortedIDs ( ) const
private

Return all registered IDs in sorted order.

Definition at line 284 of file ClassIDSvc.cxx.

285{
286 std::vector<CLID> ids;
287 ids.reserve (m_clidMap.size());
288 for (const auto& p : m_clidMap) {
289 ids.push_back (p.first);
290 }
291 std::sort (ids.begin(), ids.end());
292 return ids;
293}
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.

◆ uncheckedSetTypePackageForID()

StatusCode ClassIDSvc::uncheckedSetTypePackageForID ( const CLID & id,
const std::string & typeName,
const std::string & typeInfoName )
private

associate type name with clID w/o checking CLID range

Definition at line 398 of file ClassIDSvc.cxx.

401{
402 // process "raw" typeName
403 std::string procName(typeName);
404 boost::trim(procName);
405
406 if (procName.empty()) {
407 ATH_MSG_ERROR( "Empty type name for CLID " << id );
408 return StatusCode::FAILURE;
409 }
410
411 // assign typeInfoName
412 std::string procTiName;
413 if (typeInfoName.empty()) {
414 procTiName = procName;
415 }
416 else {
417 procTiName = typeInfoName;
418 boost::trim(procTiName);
419 }
420
421 // insert into CLID map
422 const auto& [clid_it, clid_success] = m_clidMap.try_emplace(id, procName, procTiName);
423 if (!clid_success && clid_it->second!=std::make_pair(procName,procTiName)) {
424 ATH_MSG_ERROR( "Cannot set type " << std::make_pair(procName,procTiName) << " for CLID " <<
425 id << ": known type for this ID " << clid_it->second );
426 return StatusCode::FAILURE;
427 }
428
429 // insert into type name map
430 const auto& [name_it, name_success] = m_nameMap.try_emplace(procName, id);
431 if (!name_success && name_it->second!=id) {
432 ATH_MSG_ERROR( "Cannot set CLID " << id << " for type name '"
433 << procName << "': known CLID for this name " << name_it->second );
434 return StatusCode::FAILURE;
435 }
436
437 // insert into typeInfo map
438 const auto& [info_it, info_success] = m_tiNameMap.try_emplace(procTiName, id);
439 if (!info_success && info_it->second!=id) {
440 ATH_MSG_ERROR( "Cannot set CLID " << id << " for type-info name '"
441 << procTiName << "' and type '" << procName
442 << "': known CLID for this type-info name " << info_it->second );
443 return StatusCode::FAILURE;
444 }
445
446 ATH_MSG_VERBOSE( "Set type name '" << procName << "' for CLID " << id <<
447 " with type-info name '" << procTiName << "'" );
448
449 return StatusCode::SUCCESS;
450}

Member Data Documentation

◆ m_clidDBPath

DirSearchPath ClassIDSvc::m_clidDBPath
private

The path is which clid db files are to be searched (DATAPATH)

Definition at line 129 of file ClassIDSvc.h.

◆ m_clidMap

CLIDMap ClassIDSvc::m_clidMap
private

Definition at line 124 of file ClassIDSvc.h.

◆ m_DBFiles

Gaudi::Property<std::vector<std::string> > ClassIDSvc::m_DBFiles
private
Initial value:
{this, "CLIDDBFiles", {"clid.db"},
"List of db files with (CLID, class_name) entries. Loaded at init in svc maps. Files are looked up in DATAPATH",
"OrderedSet<std::string>"}

Definition at line 117 of file ClassIDSvc.h.

117 {this, "CLIDDBFiles", {"clid.db"},
118 "List of db files with (CLID, class_name) entries. Loaded at init in svc maps. Files are looked up in DATAPATH",
119 "OrderedSet<std::string>"};

◆ m_mutex

mutex_t ClassIDSvc::m_mutex
mutableprivate

Definition at line 134 of file ClassIDSvc.h.

◆ m_nameMap

NameMap ClassIDSvc::m_nameMap
private

Definition at line 125 of file ClassIDSvc.h.

◆ m_outputFileName

Gaudi::Property<std::string> ClassIDSvc::m_outputFileName
private
Initial value:
{this, "OutputFileName", "NULL",
"Path to clid.db file for writing. By default ('NULL') to not create the file."}

Definition at line 121 of file ClassIDSvc.h.

121 {this, "OutputFileName", "NULL",
122 "Path to clid.db file for writing. By default ('NULL') to not create the file."};

◆ m_tiNameMap

NameMap ClassIDSvc::m_tiNameMap
private

Definition at line 126 of file ClassIDSvc.h.


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