10 #include "boost/algorithm/string/erase.hpp" 11 #include "boost/algorithm/string/predicate.hpp" 12 #include "boost/circular_buffer.hpp" 19 namespace ba = boost::algorithm;
21 #define ON_DEBUG if ( msgLevel( MSG::DEBUG ) ) 22 #define ON_VERBOSE if ( msgLevel( MSG::VERBOSE ) ) 28 unsigned long totalRefCount(
const C& toolList )
32 [&](
unsigned long count,
const IAlgTool* tool ) {
return count + tool->
refCount(); } );
37 void remove( C&
c,
typename C::const_reference i )
62 error() <<
"Unable to initialize the Service" <<
endmsg;
68 error() <<
"Unable to set base properties" <<
endmsg;
103 info() <<
"Removing all tools created by ToolSvc" <<
endmsg;
109 log <<
" Tool List : ";
111 log << iTool->name() <<
":" << iTool->refCount() <<
" ";
134 unsigned long startRefCount = 0;
136 unsigned long startMinRefCount = 0;
138 while ( toolCount > 0 && endRefCount > 0 && ( endRefCount != startRefCount || endMinRefCount != startMinRefCount ) ) {
139 ON_DEBUG if ( endMinRefCount != startMinRefCount )
141 debug() << toolCount <<
" tools left to finalize. Summed refCounts: " << endRefCount <<
endmsg;
142 debug() <<
"Will finalize tools with refCount <= " << endMinRefCount <<
endmsg;
144 startMinRefCount = endMinRefCount;
145 startRefCount = endRefCount;
146 unsigned long maxLoop = toolCount + 1;
151 unsigned long count = pTool->
refCount();
154 if ( count <= startMinRefCount ) {
155 ON_DEBUG debug() <<
" Performing finalization of " << toolName <<
" (refCount " << count <<
")" <<
endmsg;
163 finalizedTools.push_back( pTool );
167 ON_DEBUG debug() <<
" Delaying finalization of " << toolName <<
" (refCount " << count <<
")" <<
endmsg;
189 auto maxLoop = totalRefCount( finalizedTools ) + 1;
190 while ( --maxLoop > 0 && !finalizedTools.empty() ) {
191 IAlgTool* pTool = finalizedTools.front();
192 finalizedTools.pop_front();
199 finalizedTools.push_back( pTool );
207 error() <<
"Unable to finalize and delete the following tools : ";
209 error() << iTool->name() <<
": " << iTool->refCount() <<
" ";
215 if ( !finalizedTools.empty() ) {
216 error() <<
"Failed to delete the following " << finalizedTools.size()
217 <<
" finalized tools. Bug in ToolSvc::finalize()?: ";
218 for (
const auto& iTool : finalizedTools ) {
219 error() << iTool->name() <<
": " << iTool->refCount() <<
" ";
246 if ( ba::ends_with( tooltype, s_PUBLIC ) ) {
248 return retrieve( ba::erase_tail_copy( tooltype, s_PUBLIC.
size() ), iid, tool,
this, createIf );
252 if ( tooltype.
empty() ) {
253 error() <<
"retrieve(): No Tool Type/Name given" <<
endmsg;
256 auto pos = tooltype.
find(
'/' );
257 if ( std::string::npos == pos ) {
258 return retrieve( tooltype, tooltype, iid, tool, parent, createIf );
260 return retrieve( tooltype.
substr( 0, pos ), tooltype.
substr( pos + 1 ), iid, tool, parent, createIf );
272 if ( toolname.
empty() || ( std::string::npos != tooltype.
find(
'/' ) ) ) {
273 return retrieve( tooltype, iid, tool, parent, createIf );
277 if ( ba::ends_with( toolname, s_PUBLIC ) ) {
279 return retrieve( tooltype, ba::erase_tail_copy( toolname, s_PUBLIC.
size() ), iid, tool,
this, createIf );
290 if ( !parent ) parent =
this;
296 [&](
const IAlgTool* i ) {
return i->
name() == fullname && i->
parent() == parent; } );
306 warning() <<
"Tool " << toolname <<
" not found and creation not requested" <<
endmsg;
309 sc =
create( tooltype, toolname, parent, itool );
318 error() <<
"Tool " << toolname <<
" either does not implement the correct interface, or its version is incompatible" 338 if ( tool->type() == toolType ) tools.
push_back( tool->name() );
367 unsigned long count = tool->
refCount();
374 debug() <<
" Performing finalization of " << tool->
name() <<
" (refCount " << count <<
")" <<
endmsg;
378 debug() <<
"Performing finalization and deletion of " << tool->
name() <<
endmsg;
394 return create( tooltype, toolname, parent, tool );
401 template <
typename T>
402 class ToolCreateGuard
410 explicit ToolCreateGuard( T& tools ) : m_tools( tools ) {}
414 ToolCreateGuard( ToolCreateGuard&& ) noexcept =
default;
419 if ( m_tool )
remove( m_tools, m_tool.
get() );
420 m_tool = AlgTool::Factory::create( tooltype, tooltype, fullname, parent );
422 if ( m_tool ) m_tools.push_back( m_tool.
get() );
436 if ( m_tool )
remove( m_tools, m_tool.
get() );
440 template <
typename C>
441 ToolCreateGuard<C> make_toolCreateGuard( C&
c )
443 return ToolCreateGuard<C>{c};
463 error() <<
"create(): No Tool Type given" <<
endmsg;
468 if ( !parent ) parent =
this;
483 error() <<
"Tool " << fullname <<
" already exists with the same parent" <<
endmsg;
484 if ( parent ==
this )
485 error() <<
"... In addition, the parent is the ToolSvc: public tools cannot be cloned!" <<
endmsg;
494 toolguard.create( tooltype, fullname, parent );
495 if (
UNLIKELY( !toolguard.get() ) ) {
496 error() <<
"Cannot create tool " << tooltype <<
" (No factory found)" <<
endmsg;
501 fatal() <<
"Exception with tag=" << Exception.
tag() <<
" is caught whilst instantiating tool '" << tooltype <<
"'" 509 fatal() <<
"Standard std::exception is caught whilst instantiating tool '" << tooltype <<
"'" <<
endmsg;
516 fatal() <<
"UNKNOWN Exception is caught whilst instantiating tool '" << tooltype <<
"'" <<
endmsg;
528 error() <<
"Error setting properties for tool '" << fullname <<
"'" <<
endmsg;
536 sc = toolguard->sysInitialize();
540 error() <<
"GaudiException with tag=" << Exception.
tag() <<
" caught whilst initializing tool '" << fullname <<
"'" 541 << endmsg << Exception <<
endmsg;
544 error() <<
"Standard std::exception caught whilst initializing tool '" << fullname <<
"'" << endmsg
548 error() <<
"UNKNOWN Exception caught whilst initializing tool '" << fullname <<
"'" <<
endmsg;
554 error() <<
"Error initializing tool '" << fullname <<
"'" <<
endmsg;
560 sc = toolguard->sysStart();
563 error() <<
"Error starting tool '" << fullname <<
"'" <<
endmsg;
595 if ( named_parent ) {
596 auto fullname = named_parent->name() +
"." +
toolname;
600 error() <<
"Private Tools only allowed for components implementing INamedInterface" <<
endmsg;
611 [&](
const IAlgTool* tool ) {
return tool->
name() == fullname; } );
626 sc = itool->sysFinalize();
630 error() <<
"GaudiException with tag=" << Exception.
tag() <<
" caught whilst finalizing tool '" << toolName <<
"'" 634 error() <<
"Standard std::exception caught whilst finalizing tool '" << toolName <<
"'" <<
endmsg 638 error() <<
"UNKNOWN Exception caught whilst finalizing tool '" << toolName <<
"'" <<
endmsg;
687 if (
UNLIKELY( !iTool->sysStart().isSuccess() ) ) {
689 error() << iTool->name() <<
" failed to start()" <<
endmsg;
694 error() <<
"One or more AlgTools failed to start()" <<
endmsg;
711 if (
UNLIKELY( !iTool->sysStop().isSuccess() ) ) {
713 error() << iTool->name() <<
" failed to stop()" <<
endmsg;
718 error() <<
"One or more AlgTools failed to stop()" <<
endmsg;
constexpr static const auto FAILURE
Gaudi::StateMachine::State m_targetState
Service state.
StatusCode initialize() override
Define general base for Gaudi exception.
const std::string & name() const override
Retrieve name of the service.
Gaudi::StateMachine::State m_state
Service state.
StatusCode finalize() override
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
#define DECLARE_COMPONENT(type)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
This class is used for returning status codes from appropriate routines.
virtual StatusCode registerAlgTool(const IAlgTool &)=0
Definition of the basic interface.
virtual const std::string & tag() const
name tag for the exception, or exception type
StatusCode setProperties()
Method for setting declared properties to the values specified for the job.
constexpr static const auto SUCCESS
virtual unsigned long release()=0
Release Interface instance.
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
const StatusCode & ignore() const
Ignore/check StatusCode.
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.
virtual unsigned long refCount() const =0
Current reference count.
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
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.