| The Gaudi Framework v27r1

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

ToolSvc.cpp
Go to the documentation of this file.
1 // Include Files
2 #include "GaudiKernel/MsgStream.h"
3 #include "GaudiKernel/Service.h"
4 #include "GaudiKernel/ISvcLocator.h"
5 #include "GaudiKernel/IAlgorithm.h"
6 #include "GaudiKernel/GaudiException.h"
7 #include "GaudiKernel/AlgTool.h"
8 #include "GaudiKernel/IHistorySvc.h"
9 #include "ToolSvc.h"
10 #include <algorithm>
11 #include <map>
12 #include <string>
13 #include <cassert>
14 #include <functional>
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;
19
20 #define ON_DEBUG if (msgLevel(MSG::DEBUG))
21 #define ON_VERBOSE if (msgLevel(MSG::VERBOSE))
22
23 namespace {
24 //------------------------------------------------------------------------------
25 template <typename C>
26 unsigned long totalRefCount( const C& toolList )
27 //------------------------------------------------------------------------------
28 {
29 return std::accumulate( std::begin(toolList), std::end(toolList), 0ul,
30 [&](unsigned long count, const IAlgTool* tool ) {
31 return count + tool->refCount();
32 });
33 }
34
36 template <typename C> void remove(C& c, typename C::const_reference i) {
37 c.erase( std::remove(std::begin(c),std::end(c),i), std::end(c) );
38 }
39
40 }
41
42 // Instantiation of a static factory class used by clients to create
43 // instances of this service
44 DECLARE_COMPONENT(ToolSvc)
45
46 //------------------------------------------------------------------------------
47 ToolSvc::ToolSvc( const std::string& name, ISvcLocator* svc )
48 //------------------------------------------------------------------------------
49 : base_class( name, svc) { }
50
51 //------------------------------------------------------------------------------
52 StatusCode ToolSvc::initialize()
53 //------------------------------------------------------------------------------
54 {
55
56 // initialize the Service Base class
57 StatusCode status = Service::initialize();
58 if (UNLIKELY(status.isFailure()))
59 {
60 error() << "Unable to initialize the Service" << endmsg;
61 return status;
62 }
63
64 // set my own (ToolSvc) properties via the jobOptionService
65 if (UNLIKELY(setProperties().isFailure())) {
66 error() << "Unable to set base properties" << endmsg;
67 return StatusCode::FAILURE;
68 }
69
70 return status;
71 }
72
73 //------------------------------------------------------------------------------
74 StatusCode ToolSvc::finalize()
75 //------------------------------------------------------------------------------
76 {
77 // Finalize and delete all left-over tools. Normally all tools created with
78 // ToolSvc are left over, since ToolSvc holds a refCount (via AlgTool ctor).
79 // Several cases need to be covered:
80 // 1) Simple dependencies: no circular dependencies between tools,
81 // and tools not using other tools
82 // 2) Tools-using-tools (but no circular dependencies)
83 // a) release() is called in the tool::finalize() (e.g. via GaudiAlgorithm)
84 // b) release() is called in the tool destructor (e.g. via ToolHandle)
85 // 3) Circular dependencies between tools
86 // a) release() is called in the tool::finalize() (e.g. via GaudiAlgorithm)
87 // b) release() is called in the tool destructor (e.g. via ToolHandle)
88 // 4) In addition to each of the above cases, refCounting of a particular tool
89 // might not have been done correctly in the code. Typically release()
90 // is not called, so we are left with a too high refCount.
91 // What to do with those, and how to avoid a crash while handling them...
92
101 info() << "Removing all tools created by ToolSvc" << endmsg;
102
103 // Print out list of tools
104 ON_DEBUG {
105 auto &log = debug();
106 log << " Tool List : ";
107 for ( const auto& iTool : m_instancesTools ) {
108 log << iTool->name() << ":" << iTool->refCount( ) << " ";
109 }
110 log << endmsg;
111 }
112
113 //
114 // first pass: Finalize all tools (but don't delete them)
115 //
128 boost::circular_buffer<IAlgTool*> finalizedTools(m_instancesTools.size()); // list of tools that have been finalized
129 bool fail(false);
130 size_t toolCount = m_instancesTools.size();
131 unsigned long startRefCount = 0;
132 unsigned long endRefCount = totalToolRefCount();
133 unsigned long startMinRefCount = 0;
134 unsigned long endMinRefCount = minimumToolRefCount();
135 while ( toolCount > 0 &&
136 endRefCount > 0 &&
137 (endRefCount != startRefCount || endMinRefCount != startMinRefCount) ) {
138 ON_DEBUG if ( endMinRefCount != startMinRefCount ) {
139 debug() << toolCount << " tools left to finalize. Summed refCounts: "
140 << endRefCount << endmsg;
141 debug() << "Will finalize tools with refCount <= "
142 << endMinRefCount << endmsg;
143 }
144 startMinRefCount = endMinRefCount;
145 startRefCount = endRefCount;
146 unsigned long maxLoop = toolCount + 1;
147 while ( --maxLoop > 0 && !m_instancesTools.empty() ) {
148 IAlgTool* pTool = m_instancesTools.back();
149 // removing tool from list makes ToolSvc::releaseTool( IAlgTool* ) a noop
150 m_instancesTools.pop_back();
151 unsigned long count = pTool->refCount( );
152 // cache tool name
153 const std::string& toolName = pTool->name();
154 if ( count <= startMinRefCount ) {
155 ON_DEBUG debug() << " Performing finalization of " << toolName
156 << " (refCount " << count << ")" << endmsg;
157 // finalize of one tool may trigger a release of another tool
158 // pTool->sysFinalize().ignore();
159 if (!finalizeTool(pTool).isSuccess()) {
160 warning() << " FAILURE finalizing " << toolName << endmsg;
161 fail = true;
162 }
163 // postpone deletion
164 finalizedTools.push_back(pTool);
165 } else {
166 // Place back at the front of the list to try again later
167 // ToolSvc::releaseTool( IAlgTool* ) remains active for this tool
168 ON_DEBUG debug() << " Delaying finalization of " << toolName
169 << " (refCount " << count << ")" << endmsg;
170 m_instancesTools.insert( std::begin(m_instancesTools), pTool );
171 }
172 } // end of inner loop
173 toolCount = m_instancesTools.size();
174 endRefCount = totalToolRefCount();
175 endMinRefCount = minimumToolRefCount();
176 }; // end of outer loop
177
178 //
179 // Second pass: Delete all finalized tools
180 //
181 // Delete in the order of increasing number of refCounts.
182 // Loop over tools in the same order as the order in which they were finalized.
183 // All tools in the list of finalized tools are no longer in the instancesTools list.
184 // If a tool destructor calls releaseTool() on another tool, this will have no
185 // effect on the 'other tool' if this 'other tool' is in the list of finalized tools.
186 // If this 'other tool' is still in the instancesTools list, it may trigger finalization
187 // (in releaseTool()), deletion and removal from the instancesTools list.
188 // Therefore, the check on non-finalised tools should happen *after* the deletion
189 // of the finalized tools.
190 ON_DEBUG debug() << "Deleting " << finalizedTools.size() << " finalized tools" << endmsg;
191 auto maxLoop = totalRefCount( finalizedTools ) + 1;
192 while ( --maxLoop > 0 && !finalizedTools.empty() ) {
193 IAlgTool* pTool = finalizedTools.front();
194 finalizedTools.pop_front();
195 auto count = pTool->refCount( );
196 if ( count == 1 ) {
197 ON_DEBUG debug() << " Performing deletion of " << pTool->name() << endmsg;
198 } else {
199 ON_VERBOSE verbose() << " Delaying deletion of " << pTool->name()
200 << " (refCount " << count << ")" << endmsg;
201 // Move to the end when refCount still not zero
202 finalizedTools.push_back(pTool);
203 }
204 // do a forced release
205 pTool->release();
206 }
207
208 // Error if by now not all tools are properly finalised
209 if ( !m_instancesTools.empty() ) {
210 error() << "Unable to finalize and delete the following tools : ";
211 for ( const auto& iTool : m_instancesTools ) {
212 error() << iTool->name() << ": " << iTool->refCount( ) << " ";
213 }
214 error() << endmsg;
215 }
216
217 // by now, all tools should be deleted and removed.
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( ) << " ";
223 }
224 error() << endmsg;
225 }
226
227 if ( m_pHistorySvc ) m_pHistorySvc->release();
228
229 // Finalize this specific service
230 return ( Service::finalize().isSuccess() && !fail ) ?
231 StatusCode::SUCCESS :
232 StatusCode::FAILURE ;
233
234 }
235
236 // ===================================================================================
240 // ===================================================================================
241 namespace
242 {
243 static const std::string s_PUBLIC = ":PUBLIC" ;
244 }
245
246 //------------------------------------------------------------------------------
247 StatusCode ToolSvc::retrieve ( const std::string& tooltype ,
248 const InterfaceID& iid ,
249 IAlgTool*& tool ,
250 const IInterface* parent ,
251 bool createIf )
252 //------------------------------------------------------------------------------
253 {
254 // check for tools, which by name are required to be public:
255 if ( ba::ends_with( tooltype, s_PUBLIC ) ) {
256 // parent for PUBLIC tool is 'this', i.e. ToolSvc
257 return retrieve ( ba::erase_tail_copy(tooltype, s_PUBLIC.size()),
258 iid , tool , this , createIf ) ;
259 }
260
261 // protect against empty type
262 if ( tooltype.empty() ) {
263 error() << "retrieve(): No Tool Type/Name given" << endmsg;
264 return StatusCode::FAILURE;
265 }
266 auto pos = tooltype.find('/');
267 if ( std::string::npos == pos ) {
268 return retrieve ( tooltype , tooltype , iid , tool , parent , createIf );
269 }
270 return retrieve ( tooltype.substr( 0 , pos ),
271 tooltype.substr( pos + 1 ),
272 iid , tool , parent , createIf ) ;
273 }
274
275 // ===================================================================================
276
277 //------------------------------------------------------------------------------
278 StatusCode ToolSvc::retrieve ( const std::string& tooltype ,
279 const std::string& toolname ,
280 const InterfaceID& iid ,
281 IAlgTool*& tool ,
282 const IInterface* parent ,
283 bool createIf )
284 //------------------------------------------------------------------------------
285 {
286 // check the applicability of another method:
287 // ignore the provided name if it is empty or the type contains a name
288 if( toolname.empty() || (std::string::npos != tooltype.find('/')) )
289 { return retrieve ( tooltype , iid , tool , parent , createIf ) ; }
290
291 // check for tools, which by name are required to be public:
292 if ( ba::ends_with( toolname, s_PUBLIC ) )
293 {
294 // parent for PUBLIC tool is this, i.e. ToolSvc
295 return retrieve ( tooltype , ba::erase_tail_copy(toolname, s_PUBLIC.size() ),
296 iid , tool , this , createIf ) ;
297 }
298
299 std::lock_guard<CallMutex> lock(m_mut);
300
301 IAlgTool* itool = nullptr;
302 StatusCode sc(StatusCode::FAILURE);
303
304 tool = nullptr;
305
306 // If parent is not specified it means it is the ToolSvc itself
307 if( !parent ) parent = this;
308 const std::string fullname = nameTool( toolname, parent );
309
310 // Find tool in list of those already existing, and tell its
311 // interface that it has been used one more time
312 auto it = std::find_if( std::begin(m_instancesTools), std::end(m_instancesTools),
313 [&](const IAlgTool* i) {
314 return i->name() == fullname && i->parent() == parent;
315 });
316 if (it!=std::end(m_instancesTools)) {
317 ON_DEBUG debug() << "Retrieved tool " << toolname << " with parent " << parent << endmsg;
318 itool = *it;
319 }
320
321 if ( !itool ) {
322 // Instances of this tool do not exist, create an instance if desired
323 // otherwise return failure
324 if( UNLIKELY(!createIf) ) {
325 warning() << "Tool " << toolname
326 << " not found and creation not requested" << endmsg;
327 return sc;
328 }
329 sc = create( tooltype, toolname, parent, itool );
330 if ( sc.isFailure() ) { return sc; }
331 }
332
333 // Get the right interface of it
334 sc = itool->queryInterface( iid, pp_cast<void>(&tool) );
335 if( UNLIKELY(sc.isFailure()) ) {
336 error() << "Tool " << toolname
337 << " either does not implement the correct interface, or its version is incompatible"
338 << endmsg;
339 return sc;
340 }
341
345 std::for_each( std::begin(m_observers),
346 std::end(m_observers),
347 [&]( IToolSvc::Observer* obs ) { obs->onRetrieve(itool); } );
348 return sc;
349 }
350 //------------------------------------------------------------------------------
351 std::vector<std::string> ToolSvc::getInstances( const std::string& toolType )
352 //------------------------------------------------------------------------------
353 {
354
355 std::lock_guard<CallMutex> lock(m_mut);
356 std::vector<std::string> tools;
357 for(const auto& tool: m_instancesTools) {
358 if (tool->type() == toolType) tools.push_back( tool->name() );
359 }
360 return tools;
361 }
362 //------------------------------------------------------------------------------
363 std::vector<std::string> ToolSvc::getInstances() const
364 //------------------------------------------------------------------------------
365 {
366 std::lock_guard<CallMutex> lock(m_mut);
367 std::vector<std::string> tools{m_instancesTools.size()};
368 std::transform(std::begin(m_instancesTools), std::end(m_instancesTools),
369 std::begin(tools), [](const IAlgTool* t) { return t->name(); } );
370 return tools;
371 }
372 //------------------------------------------------------------------------------
373 std::vector<IAlgTool*> ToolSvc::getTools() const
374 //------------------------------------------------------------------------------
375 {
376 std::lock_guard<CallMutex> lock(m_mut);
377 return std::vector<IAlgTool*>{std::begin(m_instancesTools),
378 std::end(m_instancesTools)};
379 }
380 //------------------------------------------------------------------------------
381 StatusCode ToolSvc::releaseTool( IAlgTool* tool )
382 //------------------------------------------------------------------------------
383 {
384 std::lock_guard<CallMutex> lock(m_mut);
385 StatusCode sc(StatusCode::SUCCESS);
386 // test if tool is in known list (protect trying to access a previously deleted tool)
387 if ( m_instancesTools.rend() != std::find( m_instancesTools.rbegin(),
388 m_instancesTools.rend(),
389 tool ) ) {
390 unsigned long count = tool->refCount();
391 if ( count == 1 ) {
392 // finalize the tool
393
394 if ( Gaudi::StateMachine::OFFLINE == m_targetState ) {
395 // We are being called during ToolSvc::finalize()
396 // message format matches the one in ToolSvc::finalize()
397 debug() << " Performing finalization of " << tool->name()
398 << " (refCount " << count << ")" << endmsg;
399 // message format matches the one in ToolSvc::finalize()
400 debug() << " Performing deletion of " << tool->name() << endmsg;
401 } else {
402 debug() << "Performing finalization and deletion of " << tool->name() << endmsg;
403 }
404 sc = finalizeTool(tool);
405 // remove from known tools...
406 remove(m_instancesTools,tool);
407 }
408 tool->release();
409 }
410 return sc;
411 }
412
413 //------------------------------------------------------------------------------
414 StatusCode ToolSvc::create(const std::string& tooltype,
415 const IInterface* parent,
416 IAlgTool*& tool)
417 //------------------------------------------------------------------------------
418 {
419 const std::string & toolname = tooltype;
420 return create( tooltype, toolname, parent, tool);
421 }
422
423 namespace {
426 template <typename T>
427 class ToolCreateGuard {
429 T& m_tools;
431 std::unique_ptr<IAlgTool> m_tool;
432
433 public:
434 explicit ToolCreateGuard(T& tools): m_tools(tools) {}
435 // we don't get a move constructor by default because we
436 // have a non-trivial destructor... However, the default
437 // one is just fine...
438 ToolCreateGuard(ToolCreateGuard&&) noexcept = default;
440 void create( const std::string& tooltype, const std::string& fullname, const IInterface* parent ) {
441 // remove previous content
442 if (m_tool) remove(m_tools,m_tool.get());
443 m_tool.reset(AlgTool::Factory::create(tooltype, tooltype, fullname, parent)) ;
444 // set new content
445 if (m_tool) m_tools.push_back(m_tool.get());
446 }
448 IAlgTool* get() {
449 return m_tool.get();
450 }
451 IAlgTool* operator->() const {
452 assert(m_tool);
453 return m_tool.get();
454 }
456 IAlgTool* release() {
457 return m_tool.release();
458 }
460 ~ToolCreateGuard(){
461 if (m_tool) remove(m_tools,m_tool.get());
462 }
463 };
464
465 template <typename C>
466 ToolCreateGuard<C> make_toolCreateGuard(C& c) {
467 return ToolCreateGuard<C>{ c };
468 }
469 }
470
471 //------------------------------------------------------------------------------
479 StatusCode ToolSvc::create(const std::string& tooltype,
480 const std::string& toolname,
481 const IInterface* parent,
482 IAlgTool*& tool)
483 //------------------------------------------------------------------------------
484 {
485
486 std::lock_guard<CallMutex> lock(m_mut);
487 // protect against empty type
488 if ( UNLIKELY(tooltype.empty()) ) {
489 error() << "create(): No Tool Type given" << endmsg;
490 return StatusCode::FAILURE;
491 }
492
493 // If parent has not been specified, assume it is the ToolSvc
494 if ( !parent ) parent = this;
495
496 tool = nullptr;
497 // Automatically deletes the tool if not explicitly kept (i.e. on success).
498 // The tool is removed from the list of known tools too.
499 auto toolguard = make_toolCreateGuard(m_instancesTools);
500
501 // Check if the tool already exist : this could happen with clones
502 std::string fullname = nameTool(toolname, parent);
503 if( UNLIKELY(existsTool(fullname)) ) {
504 // Now check if the parent is the same. This allows for clones
505 for (IAlgTool* iAlgTool: m_instancesTools){
506 if ( iAlgTool->name() == toolname && iAlgTool->parent() == parent){
507 // The tool exist with this name, type and parent: this is bad!
508 // This excludes the possibility of cloning public tools intrinsecally
509 error() << "Tool " << fullname << " already exists with the same parent" << endmsg;
510 if (parent == this)
511 error() << "... In addition, the parent is the ToolSvc: public tools cannot be cloned!" << endmsg;
512
513 return StatusCode::FAILURE;
514 }
515 }
516 ON_DEBUG debug() << "Creating clone of " << fullname << endmsg;
517 }
518 // instantiate the tool using the factory
519 try {
520 toolguard.create( tooltype, fullname, parent );
521 if ( UNLIKELY(! toolguard.get()) ){
522 error() << "Cannot create tool " << tooltype << " (No factory found)" << endmsg;
523 return StatusCode::FAILURE;
524 }
525 }
526 catch ( const GaudiException& Exception ) {
527 // (1) perform the printout of message
528 fatal() << "Exception with tag=" << Exception.tag()
529 << " is caught whilst instantiating tool '" << tooltype << "'" << endmsg;
530 // (2) print the exception itself
531 // (NB! - GaudiException is a linked list of all "previous exceptions")
532 fatal() << Exception << endmsg;
533 return StatusCode::FAILURE;
534 }
535 catch( const std::exception& Exception ) {
536 // (1) perform the printout of message
537 fatal() << "Standard std::exception is caught whilst instantiating tool '"
538 << tooltype << "'" << endmsg;
539 // (2) print the exception itself
540 // (NB! - GaudiException is a linked list of all "previous exceptions")
541 fatal() << Exception.what() << endmsg;
542 return StatusCode::FAILURE;
543 }
544 catch(...) {
545 // (1) perform the printout
546 fatal() << "UNKNOWN Exception is caught whilst instantiating tool '"
547 << tooltype << "'" << endmsg;
548 return StatusCode::FAILURE;
549 }
550 ON_VERBOSE verbose() << "Created tool " << tooltype << "/" << fullname << endmsg;
551
552 // Since only AlgTool has the setProperties() method it is necessary to cast
553 // to downcast IAlgTool to AlgTool in order to set the properties via the JobOptions
554 // service
555 AlgTool* mytool = dynamic_cast<AlgTool*> (toolguard.get());
556 if ( mytool ) {
557 StatusCode sc = mytool->setProperties();
558 if ( UNLIKELY(sc.isFailure()) ) {
559 error() << "Error setting properties for tool '"
560 << fullname << "'" << endmsg;
561 return sc;
562 }
563 }
564
565 // Initialize the Tool
566 StatusCode sc (StatusCode::FAILURE,true);
567 try {
568 sc = toolguard->sysInitialize();
569 }
570 // Catch any exceptions
571 catch ( const GaudiException & Exception )
572 {
573 error()
574 << "GaudiException with tag=" << Exception.tag()
575 << " caught whilst initializing tool '" << fullname << "'" << endmsg
576 << Exception << endmsg;
577 return StatusCode::FAILURE;
578 }
579 catch( const std::exception & Exception )
580 {
581 error()
582 << "Standard std::exception caught whilst initializing tool '"
583 << fullname << "'" << endmsg << Exception.what() << endmsg;
584 return StatusCode::FAILURE;
585 }
586 catch (...)
587 {
588 error()
589 << "UNKNOWN Exception caught whilst initializing tool '"
590 << fullname << "'" << endmsg;
591 return StatusCode::FAILURE;
592 }
593
594 // Status of tool initialization
595 if ( UNLIKELY(sc.isFailure()) ) {
596 error() << "Error initializing tool '" << fullname << "'" << endmsg;
597 return sc;
598 }
599
600 // Start the tool if we are running.
601 if (m_state == Gaudi::StateMachine::RUNNING) {
602 sc = toolguard->sysStart();
603
604 if (UNLIKELY(sc.isFailure())) {
605 error() << "Error starting tool '" << fullname << "'" << endmsg;
606 return sc;
607 }
608 }
609
610
611 // The tool has been successfully created and initialized,
612 // so we inform the guard that it can release it
613 tool = toolguard.release();
614
618 std::for_each( m_observers.begin(),
619 m_observers.end(),
620 [&](IToolSvc::Observer* obs) { obs->onCreate(tool); } );
621 // TODO: replace by generic callback
622 // Register the tool with the HistorySvc
623 if (m_pHistorySvc || service("HistorySvc",m_pHistorySvc,false).isSuccess() ) {
624 m_pHistorySvc->registerAlgTool(*tool).ignore();
625 }
626 return StatusCode::SUCCESS;
627
628 }
629
630 //------------------------------------------------------------------------------
631 std::string ToolSvc::nameTool( const std::string& toolname,
632 const IInterface* parent )
633 //------------------------------------------------------------------------------
634 {
635
636 if ( !parent ) { return this->name() + "." + toolname; } // RETURN
637
638 // check that parent has a name!
639 auto named_parent = SmartIF<INamedInterface>( const_cast<IInterface*>(parent) );
640 if ( named_parent )
641 {
642 auto fullname = named_parent->name() + "." + toolname ;
643 return fullname ; // RETURN
644 }
645
646 error() << "Private Tools only allowed for components implementing INamedInterface"
647 << endmsg;
648 //
649 return "." + toolname ;
650 }
651
652 //------------------------------------------------------------------------------
653 bool ToolSvc::existsTool( const std::string& fullname) const
654 //------------------------------------------------------------------------------
655 {
656 std::lock_guard<CallMutex> lock(m_mut);
657 auto i = std::find_if( std::begin(m_instancesTools), std::end(m_instancesTools),
658 [&](const IAlgTool* tool) { return tool->name() == fullname; } );
659 return i != std::end(m_instancesTools);
660 }
661
662 //------------------------------------------------------------------------------
663 StatusCode ToolSvc::finalizeTool( IAlgTool* itool ) const
664 //------------------------------------------------------------------------------
665 {
666
667 // Cache tool name in case of errors
668 const std::string toolName = itool->name();
669 StatusCode sc;
670
671 // Finalise the tool inside a try block
672 try {
673 sc = itool->sysFinalize();
674 }
675 // Catch any exceptions
676 catch ( const GaudiException & Exception )
677 {
678 error()
679 << "GaudiException with tag=" << Exception.tag()
680 << " caught whilst finalizing tool '" << toolName << "'" << endmsg
681 << Exception << endmsg;
682 sc = StatusCode::FAILURE;
683 }
684 catch( const std::exception & Exception )
685 {
686 error()
687 << "Standard std::exception caught whilst finalizing tool '"
688 << toolName << "'" << endmsg << Exception.what() << endmsg;
689 sc = StatusCode::FAILURE;
690 }
691 catch (...)
692 {
693 error()
694 << "UNKNOWN Exception caught whilst finalizing tool '"
695 << toolName << "'" << endmsg;
696 sc = StatusCode::FAILURE;
697 }
698
699 return sc;
700
701 }
702
703 //------------------------------------------------------------------------------
704 unsigned long ToolSvc::totalToolRefCount() const
705 //------------------------------------------------------------------------------
706 {
707 return totalRefCount( m_instancesTools );
708 }
709 //------------------------------------------------------------------------------
710 unsigned long ToolSvc::minimumToolRefCount() const
711 //------------------------------------------------------------------------------
712 {
713 auto i = std::min_element( std::begin(m_instancesTools), std::end(m_instancesTools),
714 [](const IAlgTool* lhs, const IAlgTool* rhs) {
715 return lhs->refCount() < rhs->refCount();
716 } );
717 return i!=std::end(m_instancesTools) ? (*i)->refCount() : 0;
718 }
719
720 //------------------------------------------------------------------------------
721 void ToolSvc::registerObserver(IToolSvc::Observer* obs) {
722 //------------------------------------------------------------------------------
723 std::lock_guard<CallMutex> lock(m_mut);
724 if ( !obs )
725 throw GaudiException( "Received NULL pointer", this->name() + "::registerObserver", StatusCode::FAILURE );
726 m_observers.push_back(obs);
727 }
728
729 //------------------------------------------------------------------------------
730 void ToolSvc::unRegisterObserver(IToolSvc::Observer* obs) {
731 std::lock_guard<CallMutex> lock(m_mut);
732 auto i = std::find(m_observers.begin(),m_observers.end(),obs);
733 if (i!=m_observers.end()) m_observers.erase(i);
734 }
735
736 //------------------------------------------------------------------------------
737 StatusCode
738 ToolSvc::start()
739 //------------------------------------------------------------------------------
740 {
741
742 ON_DEBUG debug() << "START transition for AlgTools" << endmsg;
743
744 bool fail(false);
745 for ( auto& iTool : m_instancesTools ) {
746 ON_VERBOSE verbose() << iTool->name() << "::start()" << endmsg;
747
748 if (UNLIKELY(!iTool->sysStart().isSuccess())) {
749 fail = true;
750 error() << iTool->name() << " failed to start()" << endmsg;
751 }
752
753 }
754
755 if (UNLIKELY(fail)) {
756 error() << "One or more AlgTools failed to start()" << endmsg;
757 return StatusCode::FAILURE;
758 }
759 return StatusCode::SUCCESS;
760 }
761
762 //------------------------------------------------------------------------------
763 StatusCode
764 ToolSvc::stop()
765 //------------------------------------------------------------------------------
766 {
767
768 ON_DEBUG debug() << "STOP transition for AlgTools" << endmsg;
769
770 bool fail(false);
771 for ( auto& iTool : m_instancesTools ) {
772 ON_VERBOSE verbose() << iTool->name() << "::stop()" << endmsg;
773
774 if (UNLIKELY(!iTool->sysStop().isSuccess())) {
775 fail = true;
776 error() << iTool->name() << " failed to stop()" << endmsg;
777 }
778
779 }
780
781 if (UNLIKELY(fail)) {
782 error() << "One or more AlgTools failed to stop()" << endmsg;
783 return StatusCode::FAILURE;
784 }
785 return StatusCode::SUCCESS;
786 }
ToolSvc::m_pHistorySvc
IHistorySvc * m_pHistorySvc
Pointer to HistorySvc.
Definition: ToolSvc.h:106
ToolSvc::getInstances
std::vector< std::string > getInstances() const override
Get names of all tool instances.
Definition: ToolSvc.cpp:363
UNLIKELY
#define UNLIKELY(x)
Definition: Kernel.h:126
Service::m_targetState
Gaudi::StateMachine::State m_targetState
Service state.
Definition: Service.h:313
Service::initialize
StatusCode initialize() override
Definition: Service.cpp:68
SmartIF< INamedInterface >
std::vector::empty
T empty(T...args)
GaudiException
Define general base for Gaudi exception.
Definition: GaudiException.h:23
ISvcLocator
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
ToolSvc::releaseTool
StatusCode releaseTool(IAlgTool *tool) override
Release tool.
Definition: ToolSvc.cpp:381
Service::m_state
Gaudi::StateMachine::State m_state
Service state.
Definition: Service.h:311
ToolSvc::unRegisterObserver
void unRegisterObserver(IToolSvc::Observer *obs) override
Definition: ToolSvc.cpp:730
gaudiComponentHelp.name
name
Definition: gaudiComponentHelp.py:28
Service::finalize
StatusCode finalize() override
Definition: Service.cpp:193
MsgStream.h
CommonMessagingBase::info
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
Definition: CommonMessaging.h:124
Gaudi.Configuration.log
tuple log
Definition: Configuration.py:13
ToolSvc::nameTool
std::string nameTool(const std::string &nameByUser, const IInterface *parent)
Get Tool full name by combining nameByUser and "parent" part.
Definition: ToolSvc.cpp:631
std::vector::rend
T rend(T...args)
IToolSvc::Observer
allow call-backs when a tool is a created or retrieved
Definition: IToolSvc.h:244
IAlgorithm.h
StatusCode::isSuccess
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:76
AlgTool.h
gaudirun.c
tuple c
Definition: gaudirun.py:391
ToolSvc::minimumToolRefCount
unsigned long minimumToolRefCount() const
The minimum number of refCounts of all tools.
Definition: ToolSvc.cpp:710
ToolSvc::create
StatusCode create(const std::string &type, const IInterface *parent, IAlgTool *&tool)
Create Tool standard way with automatically assigned name.
Definition: ToolSvc.cpp:414
CommonMessagingBase::verbose
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
Definition: CommonMessaging.h:130
std
STL namespace.
ToolSvc::registerObserver
void registerObserver(IToolSvc::Observer *obs) override
Definition: ToolSvc.cpp:721
std::end
T end(T...args)
gaudirun.toolname
tuple toolname
Definition: gaudirun.py:327
std::remove
T remove(T...args)
merge_files.sc
int sc
Definition: merge_files.py:167
ToolSvc::m_observers
std::vector< IToolSvc::Observer * > m_observers
Definition: ToolSvc.h:108
ToolSvc::existsTool
bool existsTool(const std::string &toolname) const
Check if the tool instance exists.
Definition: ToolSvc.cpp:653
StatusCode::isFailure
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
ToolSvc::initialize
StatusCode initialize() override
Initialize the service.
Definition: ToolSvc.cpp:52
ToolSvc
This service manages tools.
Definition: ToolSvc.h:23
std::unique_ptr::release
T release(T...args)
DECLARE_COMPONENT
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
AlgTool::setProperties
StatusCode setProperties()
Method for setting declared properties to the values specified in the jobOptions via the job option s...
Definition: AlgTool.cpp:171
INamedInterface::name
virtual const std::string & name() const =0
Retrieve the name of the instance.
std::string
STL class.
ToolSvc::start
StatusCode start() override
Definition: ToolSvc.cpp:738
Service.h
IToolSvc::Observer::onCreate
virtual void onCreate(const IAlgTool *)
Definition: IToolSvc.h:247
Service::name
const std::string & name() const override
Retrieve name of the service.
Definition: Service.cpp:319
std::vector::push_back
T push_back(T...args)
InterfaceID
Interface ID class.
Definition: IInterface.h:30
CommonMessagingBase::error
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
Definition: CommonMessaging.h:118
ToolSvc::totalToolRefCount
unsigned long totalToolRefCount() const
The total number of refCounts on all tools in the instancesTools list.
Definition: ToolSvc.cpp:704
ToolSvc::finalizeTool
StatusCode finalizeTool(IAlgTool *itool) const
Finalize the given tool, with exception handling.
Definition: ToolSvc.cpp:663
CommonMessagingBase::warning
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
Definition: CommonMessaging.h:121
StatusCode::FAILURE
Definition: StatusCode.h:29
std::exception::what
T what(T...args)
merge_files.default
list default
Definition: merge_files.py:105
StatusCode::SUCCESS
Definition: StatusCode.h:30
StatusCode
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
IHistorySvc::registerAlgTool
virtual StatusCode registerAlgTool(const IAlgTool &)=0
GaudiException.h
IInterface
Definition of the basic interface.
Definition: IInterface.h:234
IInterface::refCount
virtual unsigned long refCount() const =0
Current reference count.
std::vector::erase
T erase(T...args)
std::vector::pop_back
T pop_back(T...args)
locker.lock
def lock(file)
Definition: locker.py:16
ToolSvc::getTools
std::vector< IAlgTool * > getTools() const override
Get pointers to all tool instances.
Definition: ToolSvc.cpp:373
IHistorySvc.h
GaudiException::tag
virtual const std::string & tag() const
name tag for the exception, or exception type
Definition: GaudiException.h:119
std::unique_ptr::reset
T reset(T...args)
std::exception
STL class.
Service::setProperties
StatusCode setProperties()
Method for setting declared properties to the values specified for the job.
Definition: Service.cpp:363
IAlgTool::parent
virtual const IInterface * parent() const =0
The parent of the concrete AlgTool.
std::unique_ptr::get
T get(T...args)
GaudiPython.GaudiAlgs.iAlgTool
iAlgTool
Definition: GaudiAlgs.py:55
std::vector::insert
T insert(T...args)
std::string::find
T find(T...args)
std::vector::size
T size(T...args)
Gaudi::StateMachine::RUNNING
Definition: StateMachine.h:16
std::vector< std::string >
IInterface::release
virtual unsigned long release()=0
Release Interface instance.
std::unique_ptr
STL class.
std::lock_guard
CommonMessagingBase::debug
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
Definition: CommonMessaging.h:127
ToolSvc::m_instancesTools
std::vector< IAlgTool * > m_instancesTools
Common Tools.
Definition: ToolSvc.h:103
std::begin
T begin(T...args)
IToolSvc::Observer::onRetrieve
virtual void onRetrieve(const IAlgTool *)
Definition: IToolSvc.h:248
AlgTool
Base class from which all the concrete tool classes should be derived.
Definition: AlgTool.h:45
IAlgTool
The interface implemented by the AlgTool base class.
Definition: IAlgTool.h:23
ON_DEBUG
#define ON_DEBUG
Definition: ToolSvc.cpp:20
ToolSvc::finalize
StatusCode finalize() override
Finalize the service.
Definition: ToolSvc.cpp:74
std::vector::back
T back(T...args)
CommonMessaging
Definition: CommonMessaging.h:58
std::string::substr
T substr(T...args)
Service::service
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.
Definition: Service.h:144
std::transform
T transform(T...args)
std::accumulate
T accumulate(T...args)
StatusCode::ignore
void ignore() const
Definition: StatusCode.h:108
CommonMessagingBase::fatal
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
Definition: CommonMessaging.h:112
ToolSvc::m_mut
CallMutex m_mut
Definition: ToolSvc.h:111
std::min_element
T min_element(T...args)
Gaudi::StateMachine::OFFLINE
Definition: StateMachine.h:13
std::for_each
T for_each(T...args)
ana.i
list i
Definition: ana.py:128
ISvcLocator.h
ToolSvc::stop
StatusCode stop() override
Definition: ToolSvc.cpp:764
ON_VERBOSE
#define ON_VERBOSE
Definition: ToolSvc.cpp:21
ToolSvc.h
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
IInterface::queryInterface
virtual StatusCode queryInterface(const InterfaceID &ti, void **pp)=0
Set the void** to the pointer to the requested interface of the instance.
ToolSvc::retrieve
StatusCode retrieve(const std::string &type, const InterfaceID &iid, IAlgTool *&tool, const IInterface *parent, bool createIf) override
Retrieve tool, create it by default as common tool if it does not already exist.
Definition: ToolSvc.cpp:247
std::vector::rbegin
T rbegin(T...args)