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 275 of file ClassIDSvc.cxx.

276 : base_class(name,svc),
277 m_clidDBPath(System::getEnv("DATAPATH"))
278{
279}
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 197 of file ClassIDSvc.cxx.

198{
200 ATH_MSG_INFO( "dump: in memory" );
201
202 for (CLID clid : sortedIDs()) {
203 auto it = m_clidMap.find (clid);
204 if (it == m_clidMap.end()) {
205 ATH_MSG_INFO( "CLID: "<< clid << " - type name: NOT FOUND" );
206 }
207 else {
208 ATH_MSG_INFO( "CLID: "<< clid << " - type name: " << it->second.first );
209 }
210 }
211 ATH_MSG_INFO( "------------------------------" );
212}
#define ATH_MSG_INFO(x)
uint32_t CLID
The Class ID type.
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
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 297 of file ClassIDSvc.cxx.

297 {
298 bool allOK(true);
299 for (const std::string& DBFile : m_DBFiles) {
300 DirSearchPath::path clidDB(DBFile);
301
302 if (clidDB.is_absolute()) {
303 allOK = processCLIDDB(clidDB.string());
304 } else {
305 std::list<DirSearchPath::path> paths(m_clidDBPath.find_all(clidDB));
306 if (paths.empty()) {
307 ATH_MSG_DEBUG( "Could not resolve clid DB path " << clidDB
308 << " using DATAPATH. Skipping it." );
309 } else {
310 for (const auto& p : paths) {
311 allOK &= processCLIDDB(p.string());
312 }
313 }
314 }
315 }
316 return StatusCode(allOK);
317}
#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.
list paths
Definition grepfile.py:35

◆ finalize()

StatusCode ClassIDSvc::finalize ( )
overridevirtual

dump CLIDmap to outputFileName;

Definition at line 244 of file ClassIDSvc.cxx.

245{
246 if (m_outputFileName != "NULL") {
247 std::ofstream outfile( m_outputFileName );
248 if ( !outfile ) {
249 ATH_MSG_ERROR( "unable to open output CLIDDB file: " << m_outputFileName );
250 return StatusCode::RECOVERABLE;
251 } else {
252 for (CLID clid : sortedIDs()) {
253 const std::string& typeName = m_clidMap[clid].first;
254 const std::string& tiName = m_clidMap[clid].second;
255 outfile << clid << "; " << typeName << "; " << tiName << std::endl;
256 }
257 ATH_MSG_INFO( "finalize: wrote " << m_clidMap.size() <<
258 " entries to output CLIDDB file: " << m_outputFileName );
259 }
260 }
261 return Service::finalize();
262}
#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 161 of file ClassIDSvc.cxx.

163{
165 maybeRescan();
166 NameMap::const_iterator iID = m_tiNameMap.find(typeInfoName);
167 if (iID != m_tiNameMap.end()) {
168 id = iID->second;
169 ATH_CONST_MSG_VERBOSE( "getIDOfTypeInfoName(" << typeInfoName << ") CLID is " << id );
170 return StatusCode::SUCCESS;
171 }
172 else {
173 ATH_CONST_MSG_VERBOSE( "getIDOfTypeInfoName(" << typeInfoName << ") no associated CLID found" );
174 return StatusCode::FAILURE;
175 }
176}
#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 137 of file ClassIDSvc.cxx.

138{
140 maybeRescan();
141
142 NameMap::const_iterator iID = m_nameMap.find(typeName);
143 if (iID != m_nameMap.end()) {
144 id = iID->second;
145 ATH_CONST_MSG_VERBOSE( "getIDOfTypeName(" << typeName << ") CLID is " << id );
146 return StatusCode::SUCCESS;
147 }
148 else if (tryNumeric (typeName, id)) {
149 ATH_CONST_MSG_VERBOSE( "getIDOfTypeName(" << typeName << ") is a numeric CLID" );
150 return StatusCode::SUCCESS;
151 }
152 else {
153 ATH_CONST_MSG_VERBOSE( "getIDOfTypeName(" << typeName << ") no associated CLID found" );
154 return StatusCode::FAILURE;
155 }
156}
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 364 of file ClassIDSvc.cxx.

365{
366 //not only this is fast, but is necessary to prevent recursion
367 if (!CLIDRegistry::hasNewEntries()) return true;
368
369 bool allOK(true);
370 size_t newEntries(0);
371 //to speed up processing we only take entries added to CLIDRegistry
372 //since last call (thanks Niels!)
373 for (const auto& [clid, typeName, typeInfoName] : CLIDRegistry::newEntries()) {
374 ATH_MSG_VERBOSE( "reading [" << clid << ", " << typeName << ", " << typeInfoName << "]" );
375 if (uncheckedSetTypePackageForID(clid, typeName, typeInfoName)) {
376 ++newEntries;
377 }
378 else {
379 allOK = false;
380 }
381 }
382
383 if (allOK) {
384 ATH_MSG_INFO( "getRegistryEntries: read " << newEntries
385 << " CLIDRegistry entries for module " << moduleName );
386 } else {
387 ATH_MSG_ERROR("getRegistryEntries: can not read CLIDRegistry entries for module "
388 << moduleName );
389 }
390
391 return allOK;
392}
#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 115 of file ClassIDSvc.cxx.

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

◆ getTypeNameOfID()

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

get type name associated with clID (if any)

Definition at line 95 of file ClassIDSvc.cxx.

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

◆ handle()

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

implement IIncidentListener

Definition at line 265 of file ClassIDSvc.cxx.

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

◆ initialize()

StatusCode ClassIDSvc::initialize ( )
overridevirtual

Gaudi Service Implementation.

Definition at line 216 of file ClassIDSvc.cxx.

217{
218 ATH_MSG_VERBOSE( "Initializing " << name() ) ;
219
220 CHECK( Service::initialize() );
221
222 // set up the incident service:
223 ServiceHandle<IIncidentSvc> pIncSvc ("IncidentSvc", name());
224 CHECK( pIncSvc.retrieve() );
225
226 pIncSvc->addListener(this, ModuleLoadedIncident::TYPE(), /*priority*/ 100);
227 pIncSvc->release();
228
229 CHECK( maybeRescan() ); // calls fillDB() if not already done
230
231 return StatusCode::SUCCESS;
232}
#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 78 of file ClassIDSvc.cxx.

78 {
81 return m_clidMap.find(id) != m_clidMap.end();
82}

◆ isNameInUse()

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

check if id is used

Definition at line 86 of file ClassIDSvc.cxx.

86 {
89 return m_nameMap.find(name) != m_nameMap.end();
90}

◆ maybeRescan()

bool ClassIDSvc::maybeRescan ( ) const
private

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

Definition at line 451 of file ClassIDSvc.cxx.

452{
453 // thread-safe because calls are protected by mutex or during initialize
454 ClassIDSvc* nc ATLAS_THREAD_SAFE = const_cast<ClassIDSvc*>(this);
455
456 // read CLID database in case initialize() was not called yet (ATR-23634)
457 [[maybe_unused]] static bool fillDB ATLAS_THREAD_SAFE = nc->fillDB().isSuccess();
458
459 // make sure registry is up-to-date
460 bool status = nc->getRegistryEntries ("ALL");
461
462 return status && fillDB;
463}
#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 59 of file ClassIDSvc.cxx.

59 {
63 while (valid <= CLIDdetail::MAXCLID &&
64 m_clidMap.find(valid) != m_clidMap.end())
65 {
66 ++valid;
67 }
68
69 if (valid > CLIDdetail::MAXCLID) {
70 throw std::runtime_error("ClassIDSvc::nextAvailableID: none in range");
71 }
72
73 return valid;
74}
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 321 of file ClassIDSvc.cxx.

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

◆ reinitialize()

StatusCode ClassIDSvc::reinitialize ( )
overridevirtual

Definition at line 236 of file ClassIDSvc.cxx.

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

◆ 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 181 of file ClassIDSvc.cxx.

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

◆ sortedIDs()

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

Return all registered IDs in sorted order.

Definition at line 283 of file ClassIDSvc.cxx.

284{
285 std::vector<CLID> ids;
286 ids.reserve (m_clidMap.size());
287 for (const auto& p : m_clidMap) {
288 ids.push_back (p.first);
289 }
290 std::sort (ids.begin(), ids.end());
291 return ids;
292}
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 396 of file ClassIDSvc.cxx.

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

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: