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.