diff --git a/GaudiKernel/include/GaudiKernel/DataObjID.h b/GaudiKernel/include/GaudiKernel/DataObjID.h index f37c39e767aa1f77ea024cf52e0c5cb5204de4e5..eb6b78205273fa60ed3f5da9ca21ac0f9979cf3f 100644 --- a/GaudiKernel/include/GaudiKernel/DataObjID.h +++ b/GaudiKernel/include/GaudiKernel/DataObjID.h @@ -1,5 +1,5 @@ /***********************************************************************************\ -* (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations * +* (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations * * * * This software is distributed under the terms of the Apache version 2 licence, * * copied verbatim in the file "LICENSE". * @@ -15,6 +15,7 @@ #include <GaudiKernel/StatusCode.h> #include <iostream> +#include <memory> #include <mutex> #include <string> #include <unordered_set> @@ -48,19 +49,27 @@ class DataObjID { public: friend DataObjID_Hasher; - DataObjID() = default; - DataObjID( const DataObjID& ) = default; + DataObjID() = default; + DataObjID( const DataObjID& other ) + : m_clid( other.m_clid ), m_hash( other.m_hash ), m_key( other.m_key ), m_className( other.m_className ) {} + DataObjID( std::string key ); DataObjID( const CLID& clid, std::string key ); DataObjID( std::string className, std::string key ); - DataObjID& operator=( const DataObjID& ) = default; + DataObjID& operator=( const DataObjID& other ) { + m_clid = other.m_clid; + m_hash = other.m_hash; + m_key = other.m_key; + m_className = other.m_className; + return *this; + } /// only return the last part of the key const std::string& key() const { return m_key; } /// return the ClassName (if available) - const std::string& className() const { return m_className; } + const std::string& className() const; /// combination of the key and the ClassName, mostly for debugging std::string fullKey() const; @@ -81,22 +90,18 @@ public: private: void hashGen(); void setClid(); - void setClassName(); CLID m_clid{ 0 }; std::size_t m_hash{ 0 }; - std::string m_key{ "INVALID" }; - std::string m_className; - - static IClassIDSvc* p_clidSvc; - static std::once_flag m_ip; + std::string m_key{ "INVALID" }; + mutable std::string m_className; + mutable std::once_flag m_setClassName; }; inline DataObjID::DataObjID( std::string key ) : m_key( std::move( key ) ) { hashGen(); } inline DataObjID::DataObjID( const CLID& clid, std::string key ) : m_clid( clid ), m_key( std::move( key ) ) { - setClassName(); hashGen(); } diff --git a/GaudiKernel/src/Lib/DataObjID.cpp b/GaudiKernel/src/Lib/DataObjID.cpp index 8c8189c559c1d6ffe74a7916a834e48687774470..7b1582c2a657c85c09dcbad1fbf120be952a3b40 100644 --- a/GaudiKernel/src/Lib/DataObjID.cpp +++ b/GaudiKernel/src/Lib/DataObjID.cpp @@ -1,5 +1,5 @@ /***********************************************************************************\ -* (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations * +* (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations * * * * This software is distributed under the terms of the Apache version 2 licence, * * copied verbatim in the file "LICENSE". * @@ -13,6 +13,7 @@ #include <GaudiKernel/DataObjID.h> #include <GaudiKernel/IClassIDSvc.h> #include <GaudiKernel/ISvcLocator.h> +#include <GaudiKernel/ToStream.h> #include <functional> #include <iomanip> #include <iostream> @@ -56,31 +57,22 @@ namespace Gaudi { StatusCode parse( DataObjID& dest, std::string_view src ) { return Gaudi::Parsers::parse_( dest, quote( src ) ); } -IClassIDSvc* DataObjID::p_clidSvc( nullptr ); -std::once_flag DataObjID::m_ip; namespace { - auto getClidSvc = []( std::reference_wrapper<IClassIDSvc*> p ) { - p.get() = Gaudi::svcLocator()->service<IClassIDSvc>( "ClassIDSvc" ).get(); + /// Helper to retrieve and cache pointer to ClassIDSvc if available + IClassIDSvc* getClidSvc() { + static IClassIDSvc* clidSvc = Gaudi::svcLocator()->service<IClassIDSvc>( "ClassIDSvc" ).get(); + return clidSvc; }; -} +} // namespace void DataObjID::setClid() { - std::call_once( m_ip, getClidSvc, std::ref( p_clidSvc ) ); - if ( !p_clidSvc || p_clidSvc->getIDOfTypeName( m_className, m_clid ).isFailure() ) { + if ( !getClidSvc() || getClidSvc()->getIDOfTypeName( m_className, m_clid ).isFailure() ) { m_clid = 0; m_className = "UNKNOWN_CLASS:" + m_className; } } -void DataObjID::setClassName() { - std::call_once( m_ip, getClidSvc, std::ref( p_clidSvc ) ); - - if ( !p_clidSvc || p_clidSvc->getTypeNameOfID( m_clid, m_className ).isFailure() ) { - m_className = "UNKNOW_CLID:" + std::to_string( m_clid ); - } -} - void DataObjID::hashGen() { m_hash = ( std::hash<std::string>()( m_key ) ); if ( m_clid != 0 ) { @@ -89,15 +81,27 @@ void DataObjID::hashGen() { } } -#include <GaudiKernel/ToStream.h> std::ostream& toStream( const DataObjID& d, std::ostream& os ) { using Gaudi::Utils::toStream; - return ( d.m_clid != 0 || !d.m_className.empty() ) ? toStream( std::tie( d.m_className, d.m_key ), os ) + return ( d.m_clid != 0 || !d.className().empty() ) ? toStream( std::tie( d.className(), d.m_key ), os ) : toStream( d.m_key, os ); } +const std::string& DataObjID::className() const { + + // Set class name once if not done already + if ( m_clid !=0 && m_className.empty() ) { + std::call_once( m_setClassName, [&]() { + if ( !getClidSvc() || getClidSvc()->getTypeNameOfID( m_clid, m_className ).isFailure() ) { + m_className = "UNKNOWN_CLID:" + std::to_string( m_clid ); + } + } ); + } + return m_className; +} + std::string DataObjID::fullKey() const { - return ( m_clid == 0 && m_className.empty() ) ? m_key : ( m_className + '/' + m_key ); + return ( m_clid == 0 && m_className.empty() ) ? m_key : ( className() + '/' + m_key ); } std::string Gaudi::Details::Property::StringConverter<DataObjIDColl>::toString( const DataObjIDColl& v ) {