15 #include "boost/circular_buffer.hpp"
16 #include "boost/algorithm/string/predicate.hpp"
17 #include "boost/algorithm/string/erase.hpp"
18 namespace ba = boost::algorithm;
20 #define ON_DEBUG if (msgLevel(MSG::DEBUG))
21 #define ON_VERBOSE if (msgLevel(MSG::VERBOSE))
26 unsigned long totalRefCount(
const C& toolList )
30 [&](
unsigned long count,
const IAlgTool* tool ) {
36 template <
typename C>
void remove(C&
c,
typename C::const_reference
i) {
60 error() <<
"Unable to initialize the Service" <<
endmsg;
66 error() <<
"Unable to set base properties" <<
endmsg;
101 info() <<
"Removing all tools created by ToolSvc" <<
endmsg;
106 log <<
" Tool List : ";
108 log << iTool->name() <<
":" << iTool->refCount( ) <<
" ";
131 unsigned long startRefCount = 0;
133 unsigned long startMinRefCount = 0;
135 while ( toolCount > 0 &&
137 (endRefCount != startRefCount || endMinRefCount != startMinRefCount) ) {
138 ON_DEBUG if ( endMinRefCount != startMinRefCount ) {
139 debug() << toolCount <<
" tools left to finalize. Summed refCounts: "
141 debug() <<
"Will finalize tools with refCount <= "
142 << 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
156 <<
" (refCount " << count <<
")" <<
endmsg;
164 finalizedTools.push_back(pTool);
169 <<
" (refCount " << count <<
")" <<
endmsg;
191 auto maxLoop = totalRefCount( finalizedTools ) + 1;
192 while ( --maxLoop > 0 && !finalizedTools.empty() ) {
193 IAlgTool* pTool = finalizedTools.front();
194 finalizedTools.pop_front();
200 <<
" (refCount " << count <<
")" <<
endmsg;
202 finalizedTools.push_back(pTool);
210 error() <<
"Unable to finalize and delete the following tools : ";
212 error() << iTool->name() <<
": " << iTool->refCount( ) <<
" ";
218 if ( !finalizedTools.empty() ) {
219 error() <<
"Failed to delete the following " << finalizedTools.size()
220 <<
" finalized tools. Bug in ToolSvc::finalize()?: ";
221 for (
const auto& iTool : finalizedTools ) {
222 error() << iTool->name() <<
": " << iTool->refCount( ) <<
" ";
255 if ( ba::ends_with( tooltype, s_PUBLIC ) ) {
257 return retrieve ( ba::erase_tail_copy(tooltype, s_PUBLIC.
size()),
258 iid , tool ,
this , createIf ) ;
262 if ( tooltype.
empty() ) {
263 error() <<
"retrieve(): No Tool Type/Name given" <<
endmsg;
266 auto pos = tooltype.
find(
'/');
267 if ( std::string::npos == pos ) {
268 return retrieve ( tooltype , tooltype , iid , tool , parent , createIf );
271 tooltype.
substr( pos + 1 ),
272 iid , tool , parent , createIf ) ;
288 if( toolname.
empty() || (std::string::npos != tooltype.
find(
'/')) )
289 {
return retrieve ( tooltype , iid , tool , parent , createIf ) ; }
292 if ( ba::ends_with( toolname, s_PUBLIC ) )
295 return retrieve ( tooltype , ba::erase_tail_copy(toolname, s_PUBLIC.
size() ),
296 iid , tool ,
this , createIf ) ;
307 if( !parent ) parent =
this;
314 return i->
name() == fullname && i->
parent() == parent;
325 warning() <<
"Tool " << toolname
326 <<
" not found and creation not requested" <<
endmsg;
329 sc =
create( tooltype, toolname, parent, itool );
336 error() <<
"Tool " << toolname
337 <<
" either does not implement the correct interface, or its version is incompatible"
358 if (tool->type() == toolType) tools.
push_back( tool->name() );
390 unsigned long count = tool->
refCount();
397 debug() <<
" Performing finalization of " << tool->
name()
398 <<
" (refCount " << count <<
")" <<
endmsg;
402 debug() <<
"Performing finalization and deletion of " << tool->
name() <<
endmsg;
420 return create( tooltype, toolname, parent, tool);
426 template <
typename T>
427 class ToolCreateGuard {
434 explicit ToolCreateGuard(T& tools): m_tools(tools) {}
438 ToolCreateGuard(ToolCreateGuard&&) noexcept =
default;
440 void create( const
std::
string& tooltype, const
std::
string& fullname, const
IInterface* parent ) {
442 if (m_tool)
remove(m_tools,m_tool.
get());
443 m_tool.
reset(AlgTool::Factory::create(tooltype, tooltype, fullname, parent)) ;
445 if (m_tool) m_tools.push_back(m_tool.
get());
461 if (m_tool)
remove(m_tools,m_tool.
get());
465 template <
typename C>
466 ToolCreateGuard<C> make_toolCreateGuard(C&
c) {
467 return ToolCreateGuard<C>{ c };
489 error() <<
"create(): No Tool Type given" <<
endmsg;
494 if ( !parent ) parent =
this;
509 error() <<
"Tool " << fullname <<
" already exists with the same parent" <<
endmsg;
511 error() <<
"... In addition, the parent is the ToolSvc: public tools cannot be cloned!" <<
endmsg;
520 toolguard.create( tooltype, fullname, parent );
522 error() <<
"Cannot create tool " << tooltype <<
" (No factory found)" <<
endmsg;
528 fatal() <<
"Exception with tag=" << Exception.
tag()
529 <<
" is caught whilst instantiating tool '" << tooltype <<
"'" <<
endmsg;
537 fatal() <<
"Standard std::exception is caught whilst instantiating tool '"
538 << tooltype <<
"'" <<
endmsg;
546 fatal() <<
"UNKNOWN Exception is caught whilst instantiating tool '"
547 << tooltype <<
"'" <<
endmsg;
559 error() <<
"Error setting properties for tool '"
560 << fullname <<
"'" <<
endmsg;
568 sc = toolguard->sysInitialize();
574 <<
"GaudiException with tag=" << Exception.
tag()
575 <<
" caught whilst initializing tool '" << fullname <<
"'" << endmsg
582 <<
"Standard std::exception caught whilst initializing tool '"
583 << fullname <<
"'" << endmsg << Exception.
what() <<
endmsg;
589 <<
"UNKNOWN Exception caught whilst initializing tool '"
590 << fullname <<
"'" <<
endmsg;
596 error() <<
"Error initializing tool '" << fullname <<
"'" <<
endmsg;
602 sc = toolguard->sysStart();
605 error() <<
"Error starting tool '" << fullname <<
"'" <<
endmsg;
636 if ( !parent ) {
return this->
name() +
"." +
toolname; }
642 auto fullname = named_parent->name() +
"." +
toolname ;
646 error() <<
"Private Tools only allowed for components implementing INamedInterface"
658 [&](
const IAlgTool* tool) {
return tool->
name() == fullname; } );
673 sc = itool->sysFinalize();
679 <<
"GaudiException with tag=" << Exception.
tag()
680 <<
" caught whilst finalizing tool '" << toolName <<
"'" <<
endmsg
687 <<
"Standard std::exception caught whilst finalizing tool '"
694 <<
"UNKNOWN Exception caught whilst finalizing tool '"
695 << toolName <<
"'" <<
endmsg;
748 if (
UNLIKELY(!iTool->sysStart().isSuccess())) {
750 error() << iTool->name() <<
" failed to start()" <<
endmsg;
756 error() <<
"One or more AlgTools failed to start()" <<
endmsg;
774 if (
UNLIKELY(!iTool->sysStop().isSuccess())) {
776 error() << iTool->name() <<
" failed to stop()" <<
endmsg;
782 error() <<
"One or more AlgTools failed to stop()" <<
endmsg;
Gaudi::StateMachine::State m_targetState
Service state.
StatusCode initialize() override
Define general base for Gaudi exception.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Gaudi::StateMachine::State m_state
Service state.
StatusCode finalize() override
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
bool isSuccess() const
Test for a status code of SUCCESS.
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
bool isFailure() const
Test for a status code of FAILURE.
#define DECLARE_COMPONENT(type)
virtual const std::string & name() const =0
Retrieve the name of the instance.
const std::string & name() const override
Retrieve name of the service.
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 unsigned long refCount() const =0
Current reference count.
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.
virtual unsigned long release()=0
Release Interface instance.
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
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.
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 StatusCode queryInterface(const InterfaceID &ti, void **pp)=0
Set the void** to the pointer to the requested interface of the instance.