Go to the documentation of this file.
   20 #include <boost/algorithm/string/erase.hpp> 
   21 #include <boost/algorithm/string/predicate.hpp> 
   22 #include <boost/circular_buffer.hpp> 
   30 namespace ba = boost::algorithm;
 
   32 #define ON_DEBUG if ( msgLevel( MSG::DEBUG ) ) 
   33 #define ON_VERBOSE if ( msgLevel( MSG::VERBOSE ) ) 
   52   using extends::extends;
 
   68                        bool createIf ) 
override;
 
   72                        const IInterface* parent, 
bool createIf ) 
override;
 
   93   bool existsTool( std::string_view fullname ) 
const;
 
  106       this, 
"CheckedNamedToolsConfigured", 
false,
 
  107       "Check that tools which do not have the default name have some explicit configuration." };
 
  114 #ifdef __cpp_lib_generic_unordered_lookup 
  116       using is_transparent = void;
 
  121       using is_transparent = void;
 
  123       bool operator()( 
IAlgTool const* lhs, std::string_view rhs )
 const { 
return lhs->
name() == rhs; }
 
  124       bool operator()( std::string_view lhs, 
IAlgTool const* rhs )
 const { 
return lhs == rhs->
name(); }
 
  135 #ifdef __cpp_lib_generic_unordered_lookup 
  144 #ifdef __cpp_lib_generic_unordered_lookup 
  161 #ifdef __cpp_lib_generic_unordered_lookup 
  162       auto it = 
std::find_if( 
range.first, 
range.second, [&]( 
auto const& p ) { return p->parent() == parent; } );
 
  163       return it != 
range.second ? *it : 
nullptr;
 
  167       return it != 
range.second ? it->second : 
nullptr;
 
  187   template <
typename C>
 
  188   unsigned long totalRefCount( 
const C& toolList ) {
 
  190                             [&]( 
unsigned long count, 
const IAlgTool* 
tool ) { 
return count + 
tool->refCount(); } );
 
  194   template <
typename C>
 
  195   unsigned long minimumRefCount( 
const C& toolList ) {
 
  241   info() << 
"Removing all tools created by ToolSvc" << 
endmsg;
 
  247     log << 
"  Tool List : ";
 
  248     for ( 
const auto& iTool : 
tools ) { 
log << iTool->name() << 
":" << iTool->refCount() << 
" "; }
 
  267   boost::circular_buffer<IAlgTool*> finalizedTools( 
tools.
size() ); 
 
  270   unsigned long                     startRefCount    = 0;
 
  271   unsigned long                     endRefCount      = totalRefCount( 
tools );
 
  272   unsigned long                     startMinRefCount = 0;
 
  273   unsigned long                     endMinRefCount   = minimumRefCount( 
tools );
 
  274   while ( toolCount > 0 && endRefCount > 0 && ( endRefCount != startRefCount || endMinRefCount != startMinRefCount ) ) {
 
  275     ON_DEBUG if ( endMinRefCount != startMinRefCount ) {
 
  276       debug() << toolCount << 
" tools left to finalize. Summed refCounts: " << endRefCount << 
endmsg;
 
  277       debug() << 
"Will finalize tools with refCount <= " << endMinRefCount << 
endmsg;
 
  279     startMinRefCount      = endMinRefCount;
 
  280     startRefCount         = endRefCount;
 
  281     unsigned long maxLoop = toolCount + 1;
 
  286       unsigned long count = pTool->
refCount();
 
  289       if ( count <= startMinRefCount ) {
 
  290         ON_DEBUG debug() << 
"  Performing finalization of " << toolName << 
" (refCount " << count << 
")" << 
endmsg;
 
  294           warning() << 
"    FAILURE finalizing " << toolName << 
endmsg;
 
  298         finalizedTools.push_back( pTool );
 
  302         ON_DEBUG debug() << 
"  Delaying   finalization of " << toolName << 
" (refCount " << count << 
")" << 
endmsg;
 
  307     endRefCount    = totalRefCount( 
tools );
 
  308     endMinRefCount = minimumRefCount( 
tools );
 
  323   ON_DEBUG debug() << 
"Deleting " << finalizedTools.size() << 
" finalized tools" << 
endmsg;
 
  324   auto     maxLoop = totalRefCount( finalizedTools ) + 1;
 
  325   while ( --maxLoop > 0 && !finalizedTools.empty() ) {
 
  326     IAlgTool* pTool = finalizedTools.front();
 
  327     finalizedTools.pop_front();
 
  334       finalizedTools.push_back( pTool );
 
  342     error() << 
"Unable to finalize and delete the following tools : ";
 
  343     for ( 
const auto& iTool : 
tools ) { error() << iTool->name() << 
": " << iTool->refCount() << 
" "; }
 
  348   if ( !finalizedTools.empty() ) {
 
  349     error() << 
"Failed to delete the following " << finalizedTools.size()
 
  350             << 
" finalized tools. Bug in ToolSvc::finalize()?: ";
 
  351     for ( 
const auto& iTool : finalizedTools ) { error() << iTool->name() << 
": " << iTool->refCount() << 
" "; }
 
  374   if ( ba::ends_with( tooltype, s_PUBLIC ) ) {
 
  376     tooltype.remove_suffix( s_PUBLIC.size() );
 
  381   if ( tooltype.empty() ) {
 
  382     error() << 
"retrieve(): No Tool Type/Name given" << 
endmsg;
 
  385   auto pos = tooltype.find( 
'/' );
 
  386   if ( std::string_view::npos == pos ) { 
return retrieve( tooltype, tooltype, iid, 
tool, parent, createIf ); }
 
  387   return retrieve( tooltype.substr( 0, pos ), tooltype.substr( pos + 1 ), iid, 
tool, parent, createIf );
 
  399   if ( 
toolname.empty() || ( std::string_view::npos != tooltype.find( 
'/' ) ) ) {
 
  400     return retrieve( tooltype, iid, 
tool, parent, createIf );
 
  404   if ( ba::ends_with( 
toolname, s_PUBLIC ) ) {
 
  406     toolname.remove_suffix( s_PUBLIC.size() );
 
  415   if ( !parent ) parent = 
this;
 
  420   auto      lock  = std::scoped_lock{ 
m_mut };
 
  422   if ( itool ) { 
ON_DEBUG debug() << 
"Retrieved tool " << 
toolname << 
" with parent " << parent << 
endmsg; }
 
  428       warning() << 
"Tool " << 
toolname << 
" not found and creation not requested" << 
endmsg;
 
  438     error() << 
"Tool " << 
toolname << 
" either does not implement the correct interface, or its version is incompatible" 
  456   auto                     lock = std::scoped_lock{ 
m_mut };
 
  466   auto                     lock = std::scoped_lock{ 
m_mut };
 
  469                   []( 
const IAlgTool* 
t ) { 
return t->name(); } );
 
  476   auto lock = std::scoped_lock{ 
m_mut };
 
  483   auto       lock = std::scoped_lock{ 
m_mut };
 
  487     unsigned long count = 
tool->refCount();
 
  494         debug() << 
"  Performing finalization of " << 
tool->name() << 
" (refCount " << count << 
")" << 
endmsg;
 
  496         debug() << 
"  Performing     deletion of " << 
tool->name() << 
endmsg;
 
  498         debug() << 
"Performing finalization and deletion of " << 
tool->name() << 
endmsg;
 
  520   template <
typename T>
 
  521   class ToolCreateGuard {
 
  528     explicit ToolCreateGuard( T& tools ) : m_tools( tools ) {}
 
  532     ToolCreateGuard( ToolCreateGuard&& ) noexcept = 
default;
 
  534     void create( const 
std::
string& tooltype, const 
std::
string& fullname, const 
IInterface* parent ) {
 
  536       if ( m_tool ) { m_tools.remove( m_tool.
get() ); };
 
  537       m_tool = AlgTool::Factory::create( tooltype, tooltype, fullname, parent );
 
  539       if ( m_tool ) { m_tools.push_back( m_tool.
get() ); }
 
  551       if ( m_tool ) m_tools.remove( m_tool.
get() );
 
  555   template <
typename C>
 
  556   ToolCreateGuard<C> make_toolCreateGuard( C& 
c ) {
 
  557     return ToolCreateGuard<C>{ 
c };
 
  575   if ( tooltype.
empty() ) {
 
  576     error() << 
"create(): No Tool Type given" << 
endmsg;
 
  581   if ( !parent ) parent = 
this;
 
  586   auto lock      = std::scoped_lock{ 
m_mut };
 
  594       if ( iAlgTool->name() == 
toolname && iAlgTool->parent() == parent ) {
 
  597         error() << 
"Tool " << fullname << 
" already exists with the same parent" << 
endmsg;
 
  598         if ( parent == 
this )
 
  599           error() << 
"... In addition, the parent is the ToolSvc: public tools cannot be cloned!" << 
endmsg;
 
  608     toolguard.create( tooltype, fullname, parent );
 
  609     if ( !toolguard.get() ) {
 
  610       error() << 
"Cannot create tool " << tooltype << 
" (No factory found)" << 
endmsg;
 
  615     fatal() << 
"Exception with tag=" << Exception.tag() << 
" is caught whilst instantiating tool '" << tooltype << 
"'" 
  619     fatal() << Exception << 
endmsg;
 
  623     fatal() << 
"Standard std::exception is caught whilst instantiating tool '" << tooltype << 
"'" << 
endmsg;
 
  626     fatal() << Exception.what() << 
endmsg;
 
  630     fatal() << 
"UNKNOWN Exception is caught whilst instantiating tool '" << tooltype << 
"'" << 
endmsg;
 
  644     sc = toolguard->sysInitialize();
 
  648     error() << 
"GaudiException with tag=" << Exception.tag() << 
" caught whilst initializing tool '" << fullname << 
"'" 
  652     error() << 
"Standard std::exception caught whilst initializing tool '" << fullname << 
"'" << 
endmsg 
  653             << Exception.what() << 
endmsg;
 
  656     error() << 
"UNKNOWN Exception caught whilst initializing tool '" << fullname << 
"'" << 
endmsg;
 
  662     error() << 
"Error initializing tool '" << fullname << 
"'" << 
endmsg;
 
  669       bool                            propsSet = 
false;
 
  673         bool isSet = joSvc.
isSet( mytool->
name() + 
"." + prop->name() );
 
  674         if ( isSet ) propsSet = 
true;
 
  677         warning() << tooltype << 
"/" << fullname
 
  678                   << 
" : Explicitly named tools should be configured! (assigned name=" << 
toolname << 
", default is " 
  679                   << tooltype << 
")" << 
endmsg;
 
  686     sc = toolguard->sysStart();
 
  689       error() << 
"Error starting tool '" << fullname << 
"'" << 
endmsg;
 
  696   tool = toolguard.release();
 
  718   if ( named_parent ) {
 
  723   error() << 
"Private Tools only allowed for components implementing INamedInterface" << 
endmsg;
 
  732   auto lock = std::scoped_lock{ m_mut };
 
  733   return m_instancesTools.contains( fullname );
 
  742   const auto& toolName = itool->
name();
 
  751     error() << 
"GaudiException with tag=" << Exception.tag() << 
" caught whilst finalizing tool '" << toolName << 
"'" 
  755     error() << 
"Standard std::exception caught whilst finalizing tool '" << toolName << 
"'" << 
endmsg 
  756             << Exception.what() << 
endmsg;
 
  759     error() << 
"UNKNOWN Exception caught whilst finalizing tool '" << toolName << 
"'" << 
endmsg;
 
  771   auto lock = std::scoped_lock{ 
m_mut };
 
  773     auto lock = std::scoped_lock{ 
m_mut };
 
  788     info() << 
"Listing Data Dependencies of all Tools";
 
  793         for ( 
auto& dh : idh->
inputHandles() ) { ost << 
"\n   INPUT       " << dh->fullKey(); }
 
  794         for ( 
auto& 
id : idh->
extraInputDeps() ) { ost << 
"\n   EXTRA INPUT " << 
id; }
 
  795         for ( 
auto& dh : idh->
outputHandles() ) { ost << 
"\n   OUTPUT       " << dh->fullKey(); }
 
  797         if ( ost.
str().length() > 0 ) { info() << 
"\n" << iTool->name() << ost.
str(); }
 
  799         error() << 
"can't cast " << iTool->name() << 
" to IDataHandleHolder!" << 
endmsg;
 
  809     if ( !iTool->sysStart().isSuccess() ) {
 
  811       error() << iTool->name() << 
" failed to start()" << 
endmsg;
 
  816     error() << 
"One or more AlgTools failed to start()" << 
endmsg;
 
  833     if ( !iTool->sysStop().isSuccess() ) {
 
  835       error() << iTool->name() << 
" failed to stop()" << 
endmsg;
 
  840     error() << 
"One or more AlgTools failed to stop()" << 
endmsg;
 
  
 
virtual const DataObjIDColl & extraInputDeps() const =0
Gaudi::StateMachine::State m_state
Service state
get
decorate the vector of properties
virtual const std::string & name() const =0
Retrieve the name of the instance.
virtual StatusCode queryInterface(const InterfaceID &ti, void **pp)=0
Set the void** to the pointer to the requested interface of the instance.
StatusCode finalize() override
void bindPropertiesTo(Gaudi::Interfaces::IOptionsSvc &optsSvc)
const std::vector< IAlgTool * > & tools() const
const std::vector< Gaudi::Details::PropertyBase * > & getProperties() const override
get all properties
AttribStringParser::Iterator begin(const AttribStringParser &parser)
const std::string & name() const override
Retrieve name of the service
virtual const DataObjIDColl & extraOutputDeps() const =0
const ValueType & value() const
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Base class used to extend a class implementing other interfaces.
virtual std::vector< Gaudi::DataHandle * > inputHandles() const =0
constexpr static const auto SUCCESS
#define DECLARE_COMPONENT(type)
virtual std::vector< Gaudi::DataHandle * > outputHandles() const =0
Gaudi::StateMachine::State m_targetState
Service state
constexpr static const auto FAILURE
virtual unsigned long refCount() const =0
Current reference count.
virtual unsigned long release()=0
Release Interface instance.
Interface for a component that manages application configuration options.
StatusCode service(const std::string &name, const T *&psvc, bool createIf=true) const
Access a service by name, creating it if it doesn't already exist.
decltype(auto) range(Args &&... args)
Zips multiple containers together to form a single range.
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator
virtual bool isSet(const std::string &key) const =0
Test if an option key was explicitly set or not.