| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

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

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 #ifdef __ICC
15 // disable icc remark #177: declared but never referenced
16 // TODO: Remove. Problem with boost::lambda
17 #pragma warning(disable:177)
18 #endif
19 #include "boost/lambda/bind.hpp"
20
21 #define ON_DEBUG if (UNLIKELY(outputLevel() <= MSG::DEBUG))
22 #define ON_VERBOSE if (UNLIKELY(outputLevel() <= MSG::VERBOSE))
23
24 // Instantiation of a static factory class used by clients to create
25 // instances of this service
26 DECLARE_COMPONENT(ToolSvc)
27
28 namespace bl = boost::lambda;
29
30 //------------------------------------------------------------------------------
31 ToolSvc::ToolSvc( const std::string& name, ISvcLocator* svc )
32 //------------------------------------------------------------------------------
33 : base_class(name, svc),
34 m_pHistorySvc(0)
35 { }
36
37 //------------------------------------------------------------------------------
38 ToolSvc::~ToolSvc()
39 //------------------------------------------------------------------------------
40 {
41
42 }
43
44 //------------------------------------------------------------------------------
45 StatusCode ToolSvc::initialize()
46 //------------------------------------------------------------------------------
47 {
48
49 // initialize the Service Base class
50 StatusCode status = Service::initialize();
51 if (UNLIKELY(status.isFailure()))
52 {
53 error() << "Unable to initialize the Service" << endmsg;
54 return status;
55 }
56
57 // set my own (ToolSvc) properties via the jobOptionService
58 if (UNLIKELY(setProperties().isFailure())) {
59 error() << "Unable to set base properties" << endmsg;
60 return StatusCode::FAILURE;
61 }
62
63 return status;
64 }
65
66 //------------------------------------------------------------------------------
67 StatusCode ToolSvc::finalize()
68 //------------------------------------------------------------------------------
69 {
70 // Finalize and delete all left-over tools. Normally all tools created with
71 // ToolSvc are left over, since ToolSvc holds a refCount (via AlgTool ctor).
72 // Several cases need to be covered:
73 // 1) Simple dependencies: no circular dependencies between tools,
74 // and tools not using other tools
75 // 2) Tools-using-tools (but no circular dependencies)
76 // a) release() is called in the tool::finalize() (e.g. via GaudiAlgorithm)
77 // b) release() is called in the tool destructor (e.g. via ToolHandle)
78 // 3) Circular dependencies between tools
79 // a) release() is called in the tool::finalize() (e.g. via GaudiAlgorithm)
80 // b) release() is called in the tool destructor (e.g. via ToolHandle)
81 // 4) In addition to each of the above cases, refCounting of a particular tool
82 // might not have been done correctly in the code. Typically release()
83 // is not called, so we are left with a too high refCount.
84 // What to do with those, and how to avoid a crash while handling them...
85
94 ListTools finalizedTools; // list of tools that have been finalized
95 info() << "Removing all tools created by ToolSvc" << endmsg;
96
97 // Print out list of tools
98 ON_DEBUG {
99 MsgStream &log = debug();
100 log << " Tool List : ";
101 for ( ListTools::const_iterator iTool = m_instancesTools.begin();
102 iTool != m_instancesTools.end(); ++iTool ) {
103 log << (*iTool)->name() << ":" << refCountTool( *iTool ) << " ";
104 }
105 log << endmsg;
106 }
107
108 //
109 // first pass: Finalize all tools (but don't delete them)
110 //
123 bool fail(false);
124 size_t toolCount = m_instancesTools.size();
125 unsigned long startRefCount = 0;
126 unsigned long endRefCount = totalToolRefCount();
127 unsigned long startMinRefCount = 0;
128 unsigned long endMinRefCount = minimumToolRefCount();
129 while ( toolCount > 0 &&
130 endRefCount > 0 &&
131 (endRefCount != startRefCount || endMinRefCount != startMinRefCount) ) {
132 ON_DEBUG if ( endMinRefCount != startMinRefCount ) {
133 debug() << toolCount << " tools left to finalize. Summed refCounts: "
134 << endRefCount << endmsg;
135 debug() << "Will finalize tools with refCount <= "
136 << endMinRefCount << endmsg;
137 }
138 startMinRefCount = endMinRefCount;
139 startRefCount = endRefCount;
140 unsigned long maxLoop = toolCount + 1;
141 while ( --maxLoop > 0 && m_instancesTools.size() > 0 ) {
142 IAlgTool* pTool = m_instancesTools.back();
143 // removing tool from list makes ToolSvc::releaseTool( IAlgTool* ) a noop
144 m_instancesTools.pop_back();
145 unsigned long count = refCountTool( pTool );
146 // cache tool name
147 std::string toolName = pTool->name();
148 if ( count <= startMinRefCount ) {
149 ON_DEBUG debug() << " Performing finalization of " << toolName
150 << " (refCount " << count << ")" << endmsg;
151 // finalize of one tool may trigger a release of another tool
152 // pTool->sysFinalize().ignore();
153 if (!finalizeTool(pTool).isSuccess()) {
154 warning() << " FAILURE finalizing " << toolName << endmsg;
155 fail = true;
156 }
157 // postpone deletion
158 finalizedTools.push_back(pTool);
159 } else {
160 // Place back in list to try again later
161 // ToolSvc::releaseTool( IAlgTool* ) remains active for this tool
162 ON_DEBUG debug() << " Delaying finalization of " << toolName
163 << " (refCount " << count << ")" << endmsg;
164 m_instancesTools.push_front(pTool);
165 }
166 } // end of inner loop
167 toolCount = m_instancesTools.size();
168 endRefCount = totalToolRefCount();
169 endMinRefCount = minimumToolRefCount();
170 }; // end of outer loop
171
172 //
173 // Second pass: Delete all finalized tools
174 //
175 // Delete in the order of increasing number of refCounts.
176 // Loop over tools in the same order as the order in which they were finalized.
177 // All tools in the list of finalized tools are no longer in the instancesTools list.
178 // If a tool destructor calls releaseTool() on another tool, this will have no
179 // effect on the 'other tool' if this 'other tool' is in the list of finalized tools.
180 // If this 'other tool' is still in the instancesTools list, it may trigger finalization
181 // (in releaseTool()), deletion and removal from the instancesTools list.
182 // Therefore, the check on non-finalised tools should happen *after* the deletion
183 // of the finalized tools.
184 ON_DEBUG debug() << "Deleting " << finalizedTools.size() << " finalized tools" << endmsg;
185 unsigned long maxLoop = totalToolRefCount( finalizedTools ) + 1;
186 while ( --maxLoop > 0 && finalizedTools.size() > 0 ) {
187 IAlgTool* pTool = finalizedTools.front();
188 finalizedTools.pop_front();
189 unsigned long count = refCountTool( pTool );
190 if ( count == 1 ) {
191 ON_DEBUG debug() << " Performing deletion of " << pTool->name() << endmsg;
192 } else {
193 ON_VERBOSE verbose() << " Delaying deletion of " << pTool->name()
194 << " (refCount " << count << ")" << endmsg;
195 // Put it back at the end of the list if refCount still not zero
196 finalizedTools.push_back(pTool);
197 }
198 // do a forced release
199 pTool->release();
200 }
201
202 // Error if by now not all tools are properly finalised
203 if ( !m_instancesTools.empty() ) {
204 error() << "Unable to finalize and delete the following tools : ";
205 for ( ListTools::const_iterator iTool = m_instancesTools.begin();
206 iTool != m_instancesTools.end(); ++iTool ) {
207 error() << (*iTool)->name() << ": " << refCountTool( *iTool ) << " ";
208 }
209 error() << endmsg;
210 }
211
212 // by now, all tools should be deleted and removed.
213 if ( finalizedTools.size() > 0 ) {
214 error() << "Failed to delete the following " << finalizedTools.size()
215 << " finalized tools. Bug in ToolSvc::finalize()?: ";
216 for ( ListTools::const_iterator iTool = finalizedTools.begin();
217 iTool != finalizedTools.end(); ++iTool ) {
218 error() << (*iTool)->name() << ": " << refCountTool( *iTool ) << " ";
219 }
220 error() << endmsg;
221 }
222
223 if ( 0 != m_pHistorySvc ) {
224 m_pHistorySvc->release();
225 }
226
227 // Finalize this specific service
228 if (! Service::finalize().isSuccess() || fail) {
229 return StatusCode::FAILURE;
230 } else {
231 return StatusCode::SUCCESS;
232 }
233
234
235 }
236
237 // ===================================================================================
241 // ===================================================================================
242 namespace
243 {
244 const std::string s_PUBLIC = ":PUBLIC" ;
245 }
246
247 //------------------------------------------------------------------------------
248 StatusCode ToolSvc::retrieve ( const std::string& tooltype ,
249 const InterfaceID& iid ,
250 IAlgTool*& tool ,
251 const IInterface* parent ,
252 bool createIf )
253 //------------------------------------------------------------------------------
254 {
255
256 // protect against empty type
257 if ( tooltype.empty() ) {
258 error() << "retrieve(): No Tool Type/Name given" << endmsg;
259 return StatusCode::FAILURE;
260 }
261
262 {
263 // check for tools, which by name is required to be public:
264 const std::string::size_type pos = tooltype.find ( s_PUBLIC ) ;
265 if ( std::string::npos != pos )
266 {
267 // set parent for PUBLIC tool
268 parent = this ;
269 return retrieve ( std::string( tooltype , 0 , pos ) ,
270 iid , tool , parent , createIf ) ;
271 }
272 }
273
274 const std::string::size_type pos = tooltype.find('/');
275 if( std::string::npos == pos ) {
276 return retrieve ( tooltype , tooltype , iid , tool , parent , createIf );
277 }
278 const std::string newtype ( tooltype , 0 , pos ) ;
279 const std::string newname ( tooltype , pos + 1 , std::string::npos ) ;
280 return retrieve ( newtype , newname , iid , tool , parent , createIf ) ;
281 }
282
283 // ===================================================================================
284
285 //------------------------------------------------------------------------------
286 StatusCode ToolSvc::retrieve ( const std::string& tooltype ,
287 const std::string& toolname ,
288 const InterfaceID& iid ,
289 IAlgTool*& tool ,
290 const IInterface* parent ,
291 bool createIf )
292 //------------------------------------------------------------------------------
293 {
294 // check the applicability of another method:
295 // ignore the provided name if it is empty or the type contains a name
296 if( toolname.empty() || (std::string::npos != tooltype.find('/')) )
297 { return retrieve ( tooltype , iid , tool , parent , createIf ) ; }
298
299 {
300 // check for tools, which by name is required to be public:
301 const std::string::size_type pos = toolname.find ( s_PUBLIC ) ;
302 if ( std::string::npos != pos )
303 {
304 // set parent for PUBLIC tool
305 parent = this ;
306 return retrieve ( tooltype , std::string( toolname , 0 , pos ) ,
307 iid , tool , parent , createIf ) ;
308 }
309 }
310
311 IAlgTool* itool = 0;
312 StatusCode sc(StatusCode::FAILURE);
313
314 tool = 0;
315
316 // If parent is not specified it means it is the ToolSvc itself
317 if( 0 == parent ) {
318 parent = this;
319 }
320 const std::string fullname = nameTool( toolname, parent );
321
322 // Find tool in list of those already existing, and tell its
323 // interface that it has been used one more time
324 ListTools::const_iterator it;
325 for( it = m_instancesTools.begin(); it != m_instancesTools.end(); ++it ) {
326 if( (*it)->name() == fullname ) {
327 ON_DEBUG debug() << "Retrieved tool " << toolname << endmsg;
328 itool = *it;
329 break;
330 }
331 }
332
333 if ( 0 == itool ) {
334 // Instances of this tool do not exist, create an instance if desired
335 // otherwise return failure
336 if( UNLIKELY(!createIf) ) {
337 warning() << "Tool " << toolname
338 << " not found and creation not requested" << endmsg;
339 return sc;
340 }
341 else {
342 sc = create( tooltype, toolname, parent, itool );
343 if ( sc.isFailure() ) { return sc; }
344 }
345 }
346
347 // Get the right interface of it
348 sc = itool->queryInterface( iid, (void**)&tool);
349 if( UNLIKELY(sc.isFailure()) ) {
350 error() << "Tool " << toolname
351 << " either does not implement the correct interface, or its version is incompatible"
352 << endmsg;
353 return sc;
354 }
358 if (!m_observers.empty()) {
359 std::for_each( m_observers.begin(),
360 m_observers.end(),
361 bl::bind(&IToolSvc::Observer::onRetrieve,
362 bl::_1,
363 itool));
364 }
365
366 return sc;
367 }
368 //------------------------------------------------------------------------------
369 std::vector<std::string> ToolSvc::getInstances( const std::string& toolType )
370 //------------------------------------------------------------------------------
371 {
372
373 std::vector<std::string> tools;
374
375 ListTools::const_iterator it;
376 for (it = m_instancesTools.begin(); it != m_instancesTools.end(); ++it) {
377 if ((*it)->type() == toolType) {
378 tools.push_back( (*it)->name() );
379 }
380 }
381
382 return tools;
383
384 }
385 //------------------------------------------------------------------------------
386 StatusCode ToolSvc::releaseTool( IAlgTool* tool )
387 //------------------------------------------------------------------------------
388 {
389 StatusCode sc(StatusCode::SUCCESS);
390 // test if tool is in known list (protect trying to access a previously deleted tool)
391 if ( m_instancesTools.rend() != std::find( m_instancesTools.rbegin(),
392 m_instancesTools.rend(),
393 tool ) ) {
394 unsigned long count = refCountTool(tool);
395 if ( count == 1 ) {
396 MsgStream log( msgSvc(), name() );
397 // finalize the tool
398
399 if ( Gaudi::StateMachine::OFFLINE == m_targetState ) {
400 // We are being called during ToolSvc::finalize()
401 // message format matches the one in ToolSvc::finalize()
402 log << MSG::DEBUG << " Performing finalization of " << tool->name()
403 << " (refCount " << count << ")" << endmsg;
404 // message format matches the one in ToolSvc::finalize()
405 log << MSG::DEBUG << " Performing deletion of " << tool->name() << endmsg;
406 } else {
407 log << MSG::DEBUG << "Performing finalization and deletion of " << tool->name() << endmsg;
408 }
409 sc = finalizeTool(tool);
410 // remove from known tools...
411 m_instancesTools.remove(tool);
412 }
413 tool->release();
414 }
415
416 return sc;
417 }
418
419 //------------------------------------------------------------------------------
420 StatusCode ToolSvc::create(const std::string& tooltype,
421 const IInterface* parent,
422 IAlgTool*& tool)
423 //------------------------------------------------------------------------------
424 {
425 const std::string & toolname = tooltype;
426 return create( tooltype, toolname, parent, tool);
427 }
428
429 namespace {
432 class ToolCreateGuard {
433 public:
434 ToolCreateGuard(ToolSvc::ListTools &listTools):
435 m_list(listTools),
436 m_tool(0)
437 {}
439 void set(IAlgTool* tool) {
440 if (m_tool) { // remove previous content
441 m_list.remove(m_tool);
442 delete m_tool;
443 }
444 if (tool) { // set new content
445 m_tool = tool;
446 m_list.push_back(m_tool);
447 }
448 }
449 ToolCreateGuard& operator=(IAlgTool* tool) {
450 set(tool);
451 return *this;
452 }
454 IAlgTool* get() {
455 return m_tool;
456 }
457 IAlgTool* operator->() const {
458 assert(m_tool != 0);
459 return m_tool;
460 }
462 IAlgTool* release() {
463 IAlgTool* tool = m_tool;
464 m_tool = 0;
465 return tool;
466 }
468 ~ToolCreateGuard(){
469 set(0);
470 }
471 private:
473 ToolSvc::ListTools& m_list;
475 IAlgTool* m_tool;
476 };
477 }
478 //------------------------------------------------------------------------------
479 StatusCode ToolSvc::create(const std::string& tooltype,
480 const std::string& toolname,
481 const IInterface* parent,
482 IAlgTool*& tool)
483 //------------------------------------------------------------------------------
484 {
485 // protect against empty type
486 if ( UNLIKELY(tooltype.empty()) ) {
487 error() << "create(): No Tool Type given" << endmsg;
488 return StatusCode::FAILURE;
489 }
490
491 // If parent has not been specified, assume it is the ToolSvc
492 if ( 0 == parent ) parent = this;
493
494 tool = 0;
495 // Automatically deletes the tool if not explicitly kept (i.e. on success).
496 // The tool is removed from the list of known tools too.
497 ToolCreateGuard toolguard(m_instancesTools);
498
499 // Check if the tool already exist : this should never happen
500 const std::string fullname = nameTool(toolname, parent);
501 if( UNLIKELY(existsTool(fullname)) ) {
502 error() << "Tool " << fullname << " already exists" << endmsg;
503 return StatusCode::FAILURE;
504 }
505 // instantiate the tool using the factory
506 try {
507 toolguard = AlgTool::Factory::create(tooltype, tooltype, fullname, parent);
508 if ( UNLIKELY(! toolguard.get()) ){
509 error() << "Cannot create tool " << tooltype << " (No factory found)" << endmsg;
510 return StatusCode::FAILURE;
511 }
512 }
513 catch ( const GaudiException& Exception ) {
514 // (1) perform the printout of message
515 fatal() << "Exception with tag=" << Exception.tag()
516 << " is caught whilst instantiating tool '" << tooltype << "'" << endmsg;
517 // (2) print the exception itself
518 // (NB! - GaudiException is a linked list of all "previous exceptions")
519 fatal() << Exception << endmsg;
520 return StatusCode::FAILURE;
521 }
522 catch( const std::exception& Exception ) {
523 // (1) perform the printout of message
524 fatal() << "Standard std::exception is caught whilst instantiating tool '"
525 << tooltype << "'" << endmsg;
526 // (2) print the exception itself
527 // (NB! - GaudiException is a linked list of all "previous exceptions")
528 fatal() << Exception.what() << endmsg;
529 return StatusCode::FAILURE;
530 }
531 catch(...) {
532 // (1) perform the printout
533 fatal() << "UNKNOWN Exception is caught whilst instantiating tool '"
534 << tooltype << "'" << endmsg;
535 return StatusCode::FAILURE;
536 }
537 ON_VERBOSE verbose() << "Created tool " << tooltype << "/" << fullname << endmsg;
538
539 // Since only AlgTool has the setProperties() method it is necessary to cast
540 // to downcast IAlgTool to AlgTool in order to set the properties via the JobOptions
541 // service
542 AlgTool* mytool = dynamic_cast<AlgTool*> (toolguard.get());
543 if ( mytool != 0 ) {
544 StatusCode sc = mytool->setProperties();
545 if ( UNLIKELY(sc.isFailure()) ) {
546 error() << "Error setting properties for tool '"
547 << fullname << "'" << endmsg;
548 return sc;
549 }
550 }
551
552 // Initialize the Tool
553 StatusCode sc (StatusCode::FAILURE,true);
554 try {
555 sc = toolguard->sysInitialize();
556 }
557 // Catch any exceptions
558 catch ( const GaudiException & Exception )
559 {
560 error()
561 << "GaudiException with tag=" << Exception.tag()
562 << " caught whilst initializing tool '" << fullname << "'" << endmsg
563 << Exception << endmsg;
564 return StatusCode::FAILURE;
565 }
566 catch( const std::exception & Exception )
567 {
568 error()
569 << "Standard std::exception caught whilst initializing tool '"
570 << fullname << "'" << endmsg << Exception.what() << endmsg;
571 return StatusCode::FAILURE;
572 }
573 catch (...)
574 {
575 error()
576 << "UNKNOWN Exception caught whilst initializing tool '"
577 << fullname << "'" << endmsg;
578 return StatusCode::FAILURE;
579 }
580
581 // Status of tool initialization
582 if ( UNLIKELY(sc.isFailure()) ) {
583 error() << "Error initializing tool '" << fullname << "'" << endmsg;
584 return sc;
585 }
586
587 // Start the tool if we are running.
588 if (m_state == Gaudi::StateMachine::RUNNING) {
589 sc = toolguard->sysStart();
590
591 if (UNLIKELY(sc.isFailure())) {
592 error() << "Error starting tool '" << fullname << "'" << endmsg;
593 return sc;
594 }
595 }
596
597
598 // The tool has been successfully created and initialized,
599 // so we the guard can be released
600 tool = toolguard.release();
601
605 if (!m_observers.empty()) {
606 std::for_each( m_observers.begin(),
607 m_observers.end(),
608 bl::bind(&IToolSvc::Observer::onCreate,
609 bl::_1,
610 tool));
611 }
612 // TODO: replace by generic callback
613 // Register the tool with the HistorySvc
614 if (m_pHistorySvc != 0 ||
615 service("HistorySvc",m_pHistorySvc,false).isSuccess() ) {
616 m_pHistorySvc->registerAlgTool(*tool).ignore();
617 }
618
619 return StatusCode::SUCCESS;
620
621 }
622
623 //------------------------------------------------------------------------------
624 std::string ToolSvc::nameTool( const std::string& toolname,
625 const IInterface* parent )
626 //------------------------------------------------------------------------------
627 {
628
629 std::string fullname = "";
630 if ( parent == 0 ) { return this->name() + "." + toolname; } // RETURN
631
632
633 IInterface* cparent = const_cast<IInterface*>( parent ) ;
634 // check that parent has a name!
635 INamedInterface* _p = 0 ;
636 StatusCode sc = cparent->queryInterface( INamedInterface::interfaceID() , pp_cast<void>(&_p) ) ;
637 if ( sc.isSuccess() )
638 {
639 fullname = _p->name() + "." + toolname ;
640 _p->release() ;
641 return fullname ; // RETURN
642 }
643
644 MsgStream log ( msgSvc(), name() );
645 log << MSG::ERROR
646 << "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 for ( ListTools::const_iterator it = m_instancesTools.begin();
657 it != m_instancesTools.end(); ++it ) {
658 if ( (*it)->name() == fullname ) { return true; }
659 }
660 return false;
661 }
662
663 //------------------------------------------------------------------------------
664 StatusCode ToolSvc::finalizeTool( IAlgTool* itool ) const
665 //------------------------------------------------------------------------------
666 {
667
668 // Cache tool name in case of errors
669 const std::string toolName = itool->name();
670 StatusCode sc;
671
672 // Finalise the tool inside a try block
673 try {
674 sc = itool->sysFinalize();
675 }
676 // Catch any exceptions
677 catch ( const GaudiException & Exception )
678 {
679 error()
680 << "GaudiException with tag=" << Exception.tag()
681 << " caught whilst finalizing tool '" << toolName << "'" << endmsg
682 << Exception << endmsg;
683 sc = StatusCode::FAILURE;
684 }
685 catch( const std::exception & Exception )
686 {
687 error()
688 << "Standard std::exception caught whilst finalizing tool '"
689 << toolName << "'" << endmsg << Exception.what() << endmsg;
690 sc = StatusCode::FAILURE;
691 }
692 catch (...)
693 {
694 error()
695 << "UNKNOWN Exception caught whilst finalizing tool '"
696 << toolName << "'" << endmsg;
697 sc = StatusCode::FAILURE;
698 }
699
700 return sc;
701
702 }
703
704 //------------------------------------------------------------------------------
705 unsigned long ToolSvc::totalToolRefCount( const ToolSvc::ListTools& toolList ) const
706 //------------------------------------------------------------------------------
707 {
708 unsigned long count = 0;
709 for ( ListTools::const_iterator iTool = toolList.begin();
710 iTool != toolList.end(); ++iTool ) {
711 count += refCountTool( *iTool );
712 }
713 return count;
714 }
715
716 //------------------------------------------------------------------------------
717 unsigned long ToolSvc::totalToolRefCount() const
718 //------------------------------------------------------------------------------
719 {
720 return totalToolRefCount( m_instancesTools );
721 }
722 //------------------------------------------------------------------------------
723 unsigned long ToolSvc::minimumToolRefCount() const
724 //------------------------------------------------------------------------------
725 {
726 unsigned long count = 0;
727 if ( m_instancesTools.size() > 0 ) {
728 ListTools::const_iterator iTool = m_instancesTools.begin();
729 // start with first
730 count = refCountTool( *iTool );
731 // then compare the others
732 for( ++iTool; iTool != m_instancesTools.end(); ++iTool ) {
733 count = std::min( count, refCountTool( *iTool ) );
734 }
735 }
736 return count;
737 }
738
739 void ToolSvc::registerObserver(IToolSvc::Observer* obs) {
740 if ( 0 == obs )
741 throw GaudiException( "Received NULL pointer", this->name() + "::registerObserver", StatusCode::FAILURE );
742 m_observers.push_back(obs);
743 }
744
745 void ToolSvc::unRegisterObserver(IToolSvc::Observer* obs) {
746 std::vector<IToolSvc::Observer*>::iterator i =
747 find(m_observers.begin(),m_observers.end(),obs);
748 if (i!=m_observers.end()) m_observers.erase(i);
749 }
750
751 //------------------------------------------------------------------------------
752 StatusCode
753 ToolSvc::start()
754 //------------------------------------------------------------------------------
755 {
756
757 ON_DEBUG debug() << "START transition for AlgTools" << endmsg;
758
759 bool fail(false);
760 for ( ListTools::const_iterator iTool = m_instancesTools.begin();
761 iTool != m_instancesTools.end(); ++iTool ) {
762 ON_VERBOSE verbose() << (*iTool)->name() << "::start()" << endmsg;
763
764 if (UNLIKELY(!(*iTool)->sysStart().isSuccess())) {
765 fail = true;
766 error() << (*iTool)->name() << " failed to start()" << endmsg;
767 }
768
769 }
770
771 if (UNLIKELY(fail)) {
772 error() << "One or more AlgTools failed to start()" << endmsg;
773 return StatusCode::FAILURE;
774 } else {
775 return StatusCode::SUCCESS;
776 }
777
778 }
779
780 //------------------------------------------------------------------------------
781 StatusCode
782 ToolSvc::stop()
783 //------------------------------------------------------------------------------
784 {
785
786 ON_DEBUG debug() << "STOP transition for AlgTools" << endmsg;
787
788 bool fail(false);
789 for ( ListTools::const_iterator iTool = m_instancesTools.begin();
790 iTool != m_instancesTools.end(); ++iTool ) {
791 ON_VERBOSE verbose() << (*iTool)->name() << "::stop()" << endmsg;
792
793 if (UNLIKELY(!(*iTool)->sysStop().isSuccess())) {
794 fail = true;
795 error() << (*iTool)->name() << " failed to stop()" << endmsg;
796 }
797
798 }
799
800 if (UNLIKELY(fail)) {
801 error() << "One or more AlgTools failed to stop()" << endmsg;
802 return StatusCode::FAILURE;
803 } else {
804 return StatusCode::SUCCESS;
805 }
806
807 }