Go to the documentation of this file.
20 #include <boost/circular_buffer.hpp>
29 #define ON_DEBUG if ( msgLevel( MSG::DEBUG ) )
30 #define ON_VERBOSE if ( msgLevel( MSG::VERBOSE ) )
48 using extends::extends;
63 bool createIf )
override;
67 const IInterface* parent,
bool createIf )
override;
70 std::vector<std::string>
getInstances( std::string_view toolType )
override;
76 std::vector<IAlgTool*>
getTools()
const override;
88 bool existsTool( std::string_view fullname )
const;
100 this,
"CheckedNamedToolsConfigured",
false,
101 "Check that tools which do not have the default name have some explicit configuration." };
110 std::size_t
operator()(
IAlgTool const*
s )
const noexcept {
return std::hash<std::string_view>{}(
s->name() ); }
111 std::size_t
operator()( std::string_view
s )
const noexcept {
return std::hash<std::string_view>{}(
s ); }
119 std::unordered_multiset<IAlgTool*, Hash, Equal>
m_map;
125 auto itm = std::find_if(
range.first,
range.second, [&](
auto const& p ) { return p == tool; } );
126 if ( itm !=
range.second )
m_map.erase( itm );
143 auto it = std::find_if(
range.first,
range.second, [&](
auto const& p ) { return p->parent() == parent; } );
144 return it !=
range.second ? *it :
nullptr;
146 std::vector<IAlgTool*>
grab() && {
163 template <
typename C>
164 unsigned long totalRefCount(
const C& toolList ) {
166 [&](
unsigned long count,
const IAlgTool*
tool ) {
return count +
tool->refCount(); } );
170 template <
typename C>
171 unsigned long minimumRefCount(
const C& toolList ) {
173 [](
unsigned long c,
const IAlgTool*
tool ) {
return std::min(
c,
tool->refCount() ); } );
211 info() <<
"Removing all tools created by ToolSvc" <<
endmsg;
217 log <<
" Tool List : ";
218 for (
const auto& iTool :
tools ) {
log << iTool->name() <<
":" << iTool->refCount() <<
" "; }
237 boost::circular_buffer<IAlgTool*> finalizedTools(
tools.size() );
239 size_t toolCount =
tools.size();
240 unsigned long startRefCount = 0;
241 unsigned long endRefCount = totalRefCount(
tools );
242 unsigned long startMinRefCount = 0;
243 unsigned long endMinRefCount = minimumRefCount(
tools );
244 while ( toolCount > 0 && endRefCount > 0 && ( endRefCount != startRefCount || endMinRefCount != startMinRefCount ) ) {
245 ON_DEBUG if ( endMinRefCount != startMinRefCount ) {
246 debug() << toolCount <<
" tools left to finalize. Summed refCounts: " << endRefCount <<
endmsg;
247 debug() <<
"Will finalize tools with refCount <= " << endMinRefCount <<
endmsg;
249 startMinRefCount = endMinRefCount;
250 startRefCount = endRefCount;
251 unsigned long maxLoop = toolCount + 1;
252 while ( --maxLoop > 0 && !
tools.empty() ) {
256 unsigned long count = pTool->
refCount();
258 const std::string& toolName = pTool->
name();
259 if ( count <= startMinRefCount ) {
260 ON_DEBUG debug() <<
" Performing finalization of " << toolName <<
" (refCount " << count <<
")" <<
endmsg;
264 warning() <<
" FAILURE finalizing " << toolName <<
endmsg;
268 finalizedTools.push_back( pTool );
272 ON_DEBUG debug() <<
" Delaying finalization of " << toolName <<
" (refCount " << count <<
")" <<
endmsg;
276 toolCount =
tools.size();
277 endRefCount = totalRefCount(
tools );
278 endMinRefCount = minimumRefCount(
tools );
293 ON_DEBUG debug() <<
"Deleting " << finalizedTools.size() <<
" finalized tools" <<
endmsg;
294 auto maxLoop = totalRefCount( finalizedTools ) + 1;
295 while ( --maxLoop > 0 && !finalizedTools.empty() ) {
296 IAlgTool* pTool = finalizedTools.front();
297 finalizedTools.pop_front();
304 finalizedTools.push_back( pTool );
311 if ( !
tools.empty() ) {
312 error() <<
"Unable to finalize and delete the following tools : ";
313 for (
const auto& iTool :
tools ) { error() << iTool->name() <<
": " << iTool->refCount() <<
" "; }
318 if ( !finalizedTools.empty() ) {
319 error() <<
"Failed to delete the following " << finalizedTools.size()
320 <<
" finalized tools. Bug in ToolSvc::finalize()?: ";
321 for (
const auto& iTool : finalizedTools ) { error() << iTool->name() <<
": " << iTool->refCount() <<
" "; }
330 constexpr std::string_view s_PUBLIC =
":PUBLIC";
336 if ( tooltype.ends_with( s_PUBLIC ) ) {
338 tooltype.remove_suffix( s_PUBLIC.size() );
343 if ( tooltype.empty() ) {
344 error() <<
"retrieve(): No Tool Type/Name given" <<
endmsg;
347 auto pos = tooltype.find(
'/' );
348 if ( std::string_view::npos == pos ) {
return retrieve( tooltype, tooltype, iid,
tool, parent, createIf ); }
349 return retrieve( tooltype.substr( 0, pos ), tooltype.substr( pos + 1 ), iid,
tool, parent, createIf );
356 if (
toolname.empty() || ( std::string_view::npos != tooltype.find(
'/' ) ) ) {
357 return retrieve( tooltype, iid,
tool, parent, createIf );
361 if (
toolname.ends_with( s_PUBLIC ) ) {
363 toolname.remove_suffix( s_PUBLIC.size() );
372 if ( !parent ) parent =
this;
377 auto lock = std::scoped_lock{
m_mut };
379 if ( itool ) {
ON_DEBUG debug() <<
"Retrieved tool " <<
toolname <<
" with parent " << parent <<
endmsg; }
385 warning() <<
"Tool " <<
toolname <<
" not found and creation not requested" <<
endmsg;
388 sc =
create( std::string{ tooltype }, std::string{
toolname }, parent, itool );
395 error() <<
"Tool " <<
toolname <<
" either does not implement the correct interface, or its version is incompatible"
410 std::vector<std::string>
tools;
411 auto lock = std::scoped_lock{
m_mut };
413 if (
tool->type() == toolType )
tools.push_back(
tool->name() );
419 auto lock = std::scoped_lock{
m_mut };
422 [](
const IAlgTool*
t ) {
return t->name(); } );
427 auto lock = std::scoped_lock{
m_mut };
432 auto lock = std::scoped_lock{
m_mut };
436 unsigned long count =
tool->refCount();
443 debug() <<
" Performing finalization of " <<
tool->name() <<
" (refCount " << count <<
")" <<
endmsg;
445 debug() <<
" Performing deletion of " <<
tool->name() <<
endmsg;
447 debug() <<
"Performing finalization and deletion of " <<
tool->name() <<
endmsg;
459 const std::string&
toolname = tooltype;
466 template <
typename T>
467 class ToolCreateGuard {
471 std::unique_ptr<IAlgTool> m_tool;
474 explicit ToolCreateGuard( T& tools ) : m_tools( tools ) {}
478 ToolCreateGuard( ToolCreateGuard&& ) noexcept =
default;
480 void create( const
std::
string& tooltype, const
std::
string& fullname, const
IInterface* parent ) {
482 if ( m_tool ) { m_tools.remove( m_tool.get() ); };
483 m_tool = AlgTool::Factory::create( tooltype, tooltype, fullname, parent );
485 if ( m_tool ) { m_tools.push_back( m_tool.get() ); }
497 if ( m_tool ) m_tools.remove( m_tool.get() );
501 template <
typename C>
502 ToolCreateGuard<C> make_toolCreateGuard( C&
c ) {
503 return ToolCreateGuard<C>{
c };
518 if ( tooltype.empty() ) {
519 error() <<
"create(): No Tool Type given" <<
endmsg;
524 if ( !parent ) parent =
this;
529 auto lock = std::scoped_lock{
m_mut };
537 if ( iAlgTool->name() ==
toolname && iAlgTool->parent() == parent ) {
540 error() <<
"Tool " << fullname <<
" already exists with the same parent" <<
endmsg;
541 if ( parent ==
this )
542 error() <<
"... In addition, the parent is the ToolSvc: public tools cannot be cloned!" <<
endmsg;
551 toolguard.create( tooltype, fullname, parent );
552 if ( !toolguard.get() ) {
553 error() <<
"Cannot create tool " << tooltype <<
" (No factory found)" <<
endmsg;
558 fatal() <<
"Exception with tag=" << Exception.tag() <<
" is caught whilst instantiating tool '" << tooltype <<
"'"
562 fatal() << Exception <<
endmsg;
564 }
catch (
const std::exception& Exception ) {
566 fatal() <<
"Standard std::exception is caught whilst instantiating tool '" << tooltype <<
"'" <<
endmsg;
569 fatal() << Exception.what() <<
endmsg;
573 fatal() <<
"UNKNOWN Exception is caught whilst instantiating tool '" << tooltype <<
"'" <<
endmsg;
587 sc = toolguard->sysInitialize();
591 error() <<
"GaudiException with tag=" << Exception.tag() <<
" caught whilst initializing tool '" << fullname <<
"'"
594 }
catch (
const std::exception& Exception ) {
595 error() <<
"Standard std::exception caught whilst initializing tool '" << fullname <<
"'" <<
endmsg
596 << Exception.what() <<
endmsg;
599 error() <<
"UNKNOWN Exception caught whilst initializing tool '" << fullname <<
"'" <<
endmsg;
605 error() <<
"Error initializing tool '" << fullname <<
"'" <<
endmsg;
612 bool propsSet =
false;
616 bool isSet = joSvc.
isSet( mytool->
name() +
"." + prop->name() );
617 if ( isSet ) propsSet =
true;
620 warning() << tooltype <<
"/" << fullname
621 <<
" : Explicitly named tools should be configured! (assigned name=" <<
toolname <<
", default is "
622 << tooltype <<
")" <<
endmsg;
629 sc = toolguard->sysStart();
632 error() <<
"Error starting tool '" << fullname <<
"'" <<
endmsg;
639 tool = toolguard.release();
654 if ( !parent ) {
return std::string{ this->
name() }.append(
"." ).append( toolname ); }
658 if ( named_parent ) {
659 auto fullname = std::string{ named_parent->name() }.append(
"." ).append(
toolname );
663 error() <<
"Private Tools only allowed for components implementing INamedInterface" <<
endmsg;
665 return std::string{
"." }.append(
toolname );
669 auto lock = std::scoped_lock{
m_mut };
676 const auto& toolName = itool->
name();
685 error() <<
"GaudiException with tag=" << Exception.tag() <<
" caught whilst finalizing tool '" << toolName <<
"'"
688 }
catch (
const std::exception& Exception ) {
689 error() <<
"Standard std::exception caught whilst finalizing tool '" << toolName <<
"'" <<
endmsg
690 << Exception.what() <<
endmsg;
693 error() <<
"UNKNOWN Exception caught whilst finalizing tool '" << toolName <<
"'" <<
endmsg;
703 auto lock = std::scoped_lock{
m_mut };
705 auto lock = std::scoped_lock{
m_mut };
717 info() <<
"Listing Data Dependencies of all Tools";
721 std::ostringstream ost;
722 for (
auto& dh : idh->
inputHandles() ) { ost <<
"\n INPUT " << dh->fullKey(); }
723 for (
auto&
id : idh->
extraInputDeps() ) { ost <<
"\n EXTRA INPUT " <<
id; }
724 for (
auto& dh : idh->
outputHandles() ) { ost <<
"\n OUTPUT " << dh->fullKey(); }
726 if ( ost.str().length() > 0 ) { info() <<
"\n" << iTool->name() << ost.str(); }
728 error() <<
"can't cast " << iTool->name() <<
" to IDataHandleHolder!" <<
endmsg;
738 if ( !iTool->sysStart().isSuccess() ) {
740 error() << iTool->name() <<
" failed to start()" <<
endmsg;
745 error() <<
"One or more AlgTools failed to start()" <<
endmsg;
759 if ( !iTool->sysStop().isSuccess() ) {
761 error() << iTool->name() <<
" failed to stop()" <<
endmsg;
766 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.
SmartIF< IFace > service(const std::string &name, bool createIf=true) const
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
void for_each(ContainerOfSynced &c, Fun &&f)
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.
Interface for a component that manages application configuration options.
void accumulate(Counter &counter, const Container &container, Fun f=Identity{})
A helper function for accumulating data from a container into a counter This is internally using buff...
virtual unsigned long release() const =0
Release Interface instance.
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.