Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v31r0 (aeb156f0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
ApplicationMgr.cpp
Go to the documentation of this file.
1 // Include files
2 #include "ApplicationMgr.h"
3 
4 #include "AlgorithmManager.h"
5 #include "DLLClassManager.h"
6 #include "ServiceManager.h"
7 
10 #include "GaudiKernel/IRunable.h"
11 #include "GaudiKernel/IService.h"
13 
14 #include "GaudiKernel/MsgStream.h"
16 #include "GaudiKernel/SmartIF.h"
17 
19 
20 #include "GaudiKernel/StatusCode.h"
21 #include "GaudiKernel/System.h"
22 #include "GaudiKernel/Time.h"
23 
24 #include "GaudiCoreSvcVersion.h"
25 
26 using System::getEnv;
27 using System::isEnvSet;
28 
29 #include <algorithm>
30 #include <cassert>
31 #include <ctime>
32 #include <limits>
33 
34 #define ON_DEBUG if ( UNLIKELY( m_outputLevel <= MSG::DEBUG ) )
35 #define ON_VERBOSE if ( UNLIKELY( m_outputLevel <= MSG::VERBOSE ) )
36 
38 
39 // Implementation class for the Application Manager. In this way the
40 // ApplicationMgr class is a fully insulated concrete class. Clients
41 // (main programs) will not need to re-compile if there are changes
42 // in the implementation
43 
44 //=======================================================================
45 // Constructor
46 //=======================================================================
48  // IInterface initialization
49  addRef(); // Initial count set to 1
50 
51  // Instantiate component managers
52  m_managers[IService::interfaceID().id()] = new ServiceManager( this );
53 
54  m_svcLocator = svcManager();
55 
56  // Instantiate internal services
57  // SvcLocator/Factory HAS to be already instantiated
58  m_classManager = new DLLClassManager( this );
59 
60  AlgorithmManager* algMgr = new AlgorithmManager( this );
61  m_managers[IAlgorithm::interfaceID().id()] = algMgr;
62  // m_managers[IAlgorithm::interfaceID().id()] = new HiveAlgorithmManager(this);
63 
64  // This property is not hosted in the ApplicationMgr instance
65  declareProperty( "AlgTypeAliases", algMgr->typeAliases(),
66  "Aliases of algorithm types, to replace an algorithm type for every instance" );
67 
68  // ServiceMgr Initialization loop checking
69  svcManager()->setLoopCheckEnabled( m_loopCheck );
70 
71  m_svcMapping = {"EvtDataSvc/EventDataSvc",
72  "DetDataSvc/DetectorDataSvc",
73  "HistogramSvc/HistogramDataSvc",
74  "HbookCnv::PersSvc/HbookHistSvc",
75  "RootHistCnv::PersSvc/RootHistSvc",
76  "EvtPersistencySvc/EventPersistencySvc",
77  "DetPersistencySvc/DetectorPersistencySvc",
78  "HistogramPersistencySvc/HistogramPersistencySvc"};
79 }
80 
81 //============================================================================
82 // IInterface implementation: queryInterface::addRef()
83 //============================================================================
85  if ( !ppvi ) { return StatusCode::FAILURE; }
86 
87  // try to find own/direct interfaces:
88  StatusCode sc = base_class::queryInterface( iid, ppvi );
89  if ( sc.isSuccess() ) return sc;
90 
91  // find indirect interfaces :
92  if ( ISvcLocator::interfaceID().versionMatch( iid ) ) { return serviceLocator()->queryInterface( iid, ppvi ); }
93  if ( ISvcManager::interfaceID().versionMatch( iid ) ) { return svcManager()->queryInterface( iid, ppvi ); }
94  if ( IAlgManager::interfaceID().versionMatch( iid ) ) { return algManager()->queryInterface( iid, ppvi ); }
95  if ( IClassManager::interfaceID().versionMatch( iid ) ) { return m_classManager->queryInterface( iid, ppvi ); }
96  if ( IMessageSvc::interfaceID().versionMatch( iid ) ) {
97  *ppvi = m_messageSvc.get();
99  // Note that 0 can be a valid IMessageSvc pointer value (when used for
100  // MsgStream).
101  return StatusCode::SUCCESS;
102  }
103  *ppvi = nullptr;
104  return StatusCode::FAILURE;
105 }
106 
107 //============================================================================
108 // ApplicationMgr::i_startup()
109 //============================================================================
111 
112  StatusCode sc;
113 
114  // declare factories in current module
116 
117  // Note: we cannot use CommonMessaging methods here because MessageSvc is not there yet
118  MsgStream log( nullptr, name() );
119 
120  // Create the Message service
121  auto msgsvc = svcManager()->createService( Gaudi::Utils::TypeNameString( "MessageSvc", m_messageSvcType ) );
122  if ( !msgsvc ) {
123  log << MSG::FATAL << "Error creating MessageSvc of type " << m_messageSvcType << endmsg;
124  return StatusCode::FAILURE;
125  }
126  // Get the useful interface from Message services
127  m_messageSvc = m_svcLocator->service( "MessageSvc" );
128  if ( !m_messageSvc ) {
129  log << MSG::FATAL << "Error retrieving MessageSvc." << endmsg;
130  return StatusCode::FAILURE;
131  }
132 
133  auto jobsvc = svcManager()->createService( Gaudi::Utils::TypeNameString( "JobOptionsSvc", m_jobOptionsSvcType ) );
134  // Create the Job Options service
135  if ( !jobsvc ) {
136  log << MSG::FATAL << "Error creating JobOptionsSvc" << endmsg;
137  return StatusCode::FAILURE;
138  }
139  // Get the useful interface from Message services
140  m_jobOptionsSvc = m_svcLocator->service( "JobOptionsSvc" );
141  if ( !m_jobOptionsSvc ) {
142  log << MSG::FATAL << "Error retrieving JobOptionsSvc." << endmsg;
143  return StatusCode::FAILURE;
144  }
145 
146  auto jobOptsIProp = jobsvc.as<IProperty>();
147  if ( !jobOptsIProp ) {
148  log << MSG::FATAL << "Error locating JobOptionsSvc" << endmsg;
149  return StatusCode::FAILURE;
150  }
151  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "TYPE", m_jobOptionsType ) );
152  if ( !sc.isSuccess() ) {
153  log << MSG::FATAL << "Error setting TYPE option in JobOptionsSvc" << endmsg;
154  return sc;
155  }
156 
157  if ( !m_jobOptionsPreAction.empty() ) {
158  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PYTHONPARAMS", m_jobOptionsPreAction ) );
159  if ( !sc.isSuccess() ) {
160  log << MSG::FATAL << "Error setting JobOptionsPreAction option in JobOptionsSvc" << endmsg;
161  return sc;
162  }
163  }
164 
165  if ( !m_jobOptionsPostAction.empty() ) {
166  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PYTHONACTION", m_jobOptionsPostAction ) );
167  if ( !sc.isSuccess() ) {
168  log << MSG::FATAL << "Error setting JobOptionsPostAction option in JobOptionsSvc" << endmsg;
169  return sc;
170  }
171  }
172 
173  if ( !m_jobOptionsPath.empty() ) { // The command line takes precedence
174  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PATH", m_jobOptionsPath ) );
175  if ( !sc.isSuccess() ) {
176  log << MSG::FATAL << "Error setting PATH option in JobOptionsSvc" << endmsg;
177  return sc;
178  }
179  } else if ( isEnvSet( "JOBOPTPATH" ) ) { // Otherwise the Environment JOBOPTPATH
180  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PATH", getEnv( "JOBOPTPATH" ) ) );
181  if ( !sc.isSuccess() ) {
182  log << MSG::FATAL << "Error setting PATH option in JobOptionsSvc from env" << endmsg;
183  return sc;
184  }
185  } else { // Otherwise the default
186  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PATH", "../options/job.opts" ) );
187  if ( !sc.isSuccess() ) {
188  log << MSG::FATAL << "Error setting PATH option in JobOptionsSvc to default" << endmsg;
189  return sc;
190  }
191  }
192  jobOptsIProp.reset();
193 
194  // Sets my default the Output Level of the Message service to be
195  // the same as this
196  auto msgSvcIProp = msgsvc.as<IProperty>();
197  msgSvcIProp->setProperty( Gaudi::Property<int>( "OutputLevel", m_outputLevel ) ).ignore();
198  msgSvcIProp.reset();
199 
200  sc = jobsvc->sysInitialize();
201  if ( !sc.isSuccess() ) {
202  log << MSG::FATAL << "Error initializing JobOptionsSvc" << endmsg;
203  return sc;
204  }
205  sc = msgsvc->sysInitialize();
206  if ( !sc.isSuccess() ) {
207  log << MSG::FATAL << "Error initializing MessageSvc" << endmsg;
208  return sc;
209  }
210 
211  // Make sure output level caches are up to date.
213 
214  return sc;
215 }
216 
217 //============================================================================
218 // IAppMgrUI implementation: ApplicationMgr::configure()
219 //============================================================================
221 
222  // Check if the state is compatible with the transition
223  MsgStream tlog( m_messageSvc, name() );
225  tlog << MSG::INFO << "Already Configured" << endmsg;
226  return StatusCode::SUCCESS;
227  }
229  tlog << MSG::FATAL << "configure: Invalid state \"" << m_state << "\"" << endmsg;
230  return StatusCode::FAILURE;
231  }
233 
234  // Reset application return code.
236 
237  StatusCode sc;
238  sc = i_startup();
239  if ( !sc.isSuccess() ) { return sc; }
240 
241  {
243  // Get my own options using the Job options service
244  if ( log.level() <= MSG::DEBUG ) log << MSG::DEBUG << "Getting my own properties" << endmsg;
245  sc = m_jobOptionsSvc->setMyProperties( name(), this );
246  if ( !sc.isSuccess() ) {
247  log << MSG::WARNING << "Problems getting my properties from JobOptionsSvc" << endmsg;
248  return sc;
249  }
250  }
251 
252  // Make sure that the OutputLevel is in sync
255 
256  // Check current outputLevel to eventually inform the MessageSvc
257  if ( m_outputLevel != MSG::NIL && !m_appName.empty() ) {
258  // Print a welcome message
259  log << MSG::ALWAYS << std::endl
260  << "=================================================================="
261  << "==================================================================" << std::endl
262  << " "
263  << " Welcome to " << m_appName.value();
264 
265  if ( !m_appVersion.empty() ) {
266  log << MSG::ALWAYS << " version " << m_appVersion.value();
267  } else {
268  log << MSG::ALWAYS << " (GaudiCoreSvc "
269  << "v" << GAUDICORESVC_MAJOR_VERSION << "r" << GAUDICORESVC_MINOR_VERSION
270 #if GAUDICORESVC_PATCH_VERSION
271  << "p" << GAUDICORESVC_PATCH_VERSION
272 #endif
273  << ")";
274  }
275 
276  // Add the host name and current time to the message
277  log << MSG::ALWAYS << std::endl
278  << " "
279  << " running on " << System::hostName() << " on " << Gaudi::Time::current().format( true ) << std::endl
280  << "=================================================================="
281  << "==================================================================" << endmsg;
282  }
283 
284  // print all own properties if the options "PropertiesPrint" is set to true
285  if ( m_propertiesPrint ) {
286  const auto& properties = getProperties();
287  log << MSG::ALWAYS << "List of ALL properties of " << System::typeinfoName( typeid( *this ) ) << "/" << this->name()
288  << " #properties = " << properties.size() << endmsg;
289  for ( const auto& property : properties ) { log << "Property ['Name': Value] = " << *property << endmsg; }
290  }
291 
292  // Check if StatusCode need to be checked
293  if ( m_codeCheck ) {
295  sc = svcManager()->addService( "StatusCodeSvc", -9999 );
296  if ( sc.isFailure() ) {
297  log << MSG::FATAL << "Error adding StatusCodeSvc" << endmsg;
298  return StatusCode::FAILURE;
299  } else {
300  ON_VERBOSE
301  log << MSG::VERBOSE << "added service StatusCodeSvc" << endmsg;
302  }
303  } else {
305  }
306 
307  // set the requested environment variables
308  for ( auto& var : m_environment ) {
309  const std::string& name = var.first;
310  const std::string& value = var.second;
311  std::string old = System::getEnv( name.c_str() );
312  const MSG::Level lvl = ( !old.empty() && ( old != "UNKNOWN" ) ) ? MSG::WARNING : MSG::DEBUG;
313  if ( UNLIKELY( m_outputLevel <= lvl ) ) log << lvl << "Setting " << name << " = " << value << endmsg;
314  System::setEnv( name, value );
315  }
316 
317  // Declare Service Types
318  for ( auto& j : m_svcMapping ) {
320  if ( svcManager()->declareSvcType( itm.name(), itm.type() ).isFailure() ) {
321  log << MSG::ERROR << "configure: declaring svc type:'" << j << "' failed." << endmsg;
322  return StatusCode::FAILURE;
323  } else {
324  ON_VERBOSE
325  log << MSG::VERBOSE << "declared service " << j << endmsg;
326  }
327  }
328  for ( auto& j : m_svcOptMapping ) {
330  if ( svcManager()->declareSvcType( itm.name(), itm.type() ).isFailure() ) {
331  log << MSG::ERROR << "declaring svc type:'" << j << "' failed." << endmsg;
332  return StatusCode::FAILURE;
333  }
334  }
335 
336  //--------------------------------------------------------------------------
337  // Declare other Services and Algorithms by loading DLL's
338  sc = decodeDllNameList();
339  if ( sc.isFailure() ) {
340  log << MSG::ERROR << "Failure loading declared DLL's" << endmsg;
341  return sc;
342  }
343 
344  //--------------------------------------------------------------------------
345  // Deal with the services explicitly declared by the user.
346  sc = decodeExtSvcNameList();
347  if ( sc.isFailure() ) {
348  log << MSG::ERROR << "Failure during external service association" << endmsg;
349  return sc;
350  }
351 
353  if ( sc.isFailure() ) {
354  log << MSG::ERROR << "Failure during external service creation" << endmsg;
355  return sc;
356  }
357 
358  //--------------------------------------------------------------------------
359  // Retrieve intrinsic services. If needed configure them.
360  //--------------------------------------------------------------------------
361  const Gaudi::Utils::TypeNameString evtloop_item( m_eventLoopMgr );
362  sc = svcManager()->addService( evtloop_item, ServiceManager::DEFAULT_SVC_PRIORITY * 10 );
363  if ( !sc.isSuccess() ) {
364  log << MSG::FATAL << "Error adding :" << m_eventLoopMgr << endmsg;
365  return sc;
366  } else {
367  ON_VERBOSE
368  log << MSG::VERBOSE << "added service " << evtloop_item << endmsg;
369  }
370 
372  if ( !m_runable ) {
373  log << MSG::FATAL << "Error retrieving Runable: " << m_runableType.value() << "\n Check option ApplicationMgr."
374  << m_runableType.name() << endmsg;
375  return sc;
376  }
377  m_processingMgr = m_svcLocator->service( evtloop_item );
378  if ( !m_processingMgr ) {
379  log << MSG::FATAL << "Error retrieving Processing manager: " << m_eventLoopMgr.value()
380  << "\n Check option ApplicationMgr." << m_eventLoopMgr.name() << "\n No events will be processed." << endmsg;
381  return sc;
382  }
383 
384  // Establish Update Handlers for ExtSvc and DLLs Properties
385  m_extSvcNameList.declareUpdateHandler( &ApplicationMgr::extSvcNameListHandler, this );
386  m_createSvcNameList.declareUpdateHandler( &ApplicationMgr::createSvcNameListHandler, this );
387  m_dllNameList.declareUpdateHandler( &ApplicationMgr::dllNameListHandler, this );
388 
389  if ( m_actHistory ) {
390  // Create HistorySvc with a priority to ensure it's initialized last, finalized first
391  sc = svcManager()->addService( "HistorySvc", std::numeric_limits<int>::max() );
392  if ( sc.isFailure() ) {
393  log << MSG::FATAL << "Error adding HistorySvc" << endmsg;
394  return StatusCode::FAILURE;
395  }
396  }
397 
398  log << MSG::INFO << "Application Manager Configured successfully" << endmsg;
400  return StatusCode::SUCCESS;
401 }
402 
403 //============================================================================
404 // IAppMgrUI implementation: ApplicationMgr::initialize()
405 //============================================================================
407  StatusCode sc;
408 
410 
411  // Make sure output level caches are up to date.
413 
414  // I cannot add these services in configure() because they are coming from GaudiUtils
415  // and it messes up genconf when rebuilding it.
416  if ( m_stopOnSignal ) {
417  // Instantiate the service that schedules a stop when a signal is received
418  std::string svcname( "Gaudi::Utils::StopSignalHandler" );
419  sc = svcManager()->addService( svcname );
420  if ( sc.isFailure() ) {
421  log << MSG::INFO << "Cannot instantiate " << svcname << "signals will be ignored" << endmsg;
422  }
423  }
424 
425  if ( m_stalledEventMonitoring ) {
426  // Instantiate the service that schedules a stop when a signal is received
427  std::string svcname( "StalledEventMonitor" );
428  sc = svcManager()->addService( svcname );
429  if ( sc.isFailure() ) {
430  log << MSG::INFO << "Cannot instantiate " << svcname << "signals will be ignored" << endmsg;
431  }
432  }
433 
435  log << MSG::INFO << "Already Initialized!" << endmsg;
436  return StatusCode::SUCCESS;
437  }
439  log << MSG::FATAL << "initialize: Invalid state \"" << m_state << "\"" << endmsg;
440  return StatusCode::FAILURE;
441  }
443 
444  //--------------------------------------------------------------------------
445  // Initialize the list of top Services
446  //--------------------------------------------------------------------------
447  sc = svcManager()->initialize();
448  if ( !sc.isSuccess() ) return sc;
449 
450  sc = algManager()->initialize();
451  if ( !sc.isSuccess() ) return sc;
452 
453  //--------------------------------------------------------------------------
454  // Final steps: Inform user and change internal state
455  //--------------------------------------------------------------------------
456  log << MSG::INFO << "Application Manager Initialized successfully" << endmsg;
458 
459  return sc;
460 }
461 
462 //============================================================================
463 // IAppMgrUI implementation: ApplicationMgr::start()
464 //============================================================================
466 
468  StatusCode sc;
469 
471  log << MSG::INFO << "Already Initialized!" << endmsg;
472  return StatusCode::SUCCESS;
473  }
475  log << MSG::FATAL << "start: Invalid state \"" << m_state << "\"" << endmsg;
476  return StatusCode::FAILURE;
477  }
479 
480  //--------------------------------------------------------------------------
481  // Initialize the list of top Services
482  //--------------------------------------------------------------------------
483  sc = svcManager()->start();
484  if ( !sc.isSuccess() ) return sc;
485 
486  sc = algManager()->start();
487  if ( !sc.isSuccess() ) return sc;
488 
489  //--------------------------------------------------------------------------
490  // Final steps: Inform user and change internal state
491  //--------------------------------------------------------------------------
492  log << MSG::INFO << "Application Manager Started successfully" << endmsg;
494 
495  return sc;
496 }
497 
498 //============================================================================
499 // IAppMgrUI implementation: ApplicationMgr::nextEvent(int)
500 //============================================================================
504  log << MSG::FATAL << "nextEvent: Invalid state \"" << m_state << "\"" << endmsg;
505  return StatusCode::FAILURE;
506  }
507  if ( !m_processingMgr ) {
509  log << MSG::FATAL << "No event processing manager specified. Check option: " << m_eventLoopMgr.name() << endmsg;
510  return StatusCode::FAILURE;
511  }
512  return m_processingMgr->nextEvent( maxevt );
513 }
514 
515 //============================================================================
516 // IAppMgrUI implementation: ApplicationMgr::stop()
517 //============================================================================
519 
521  StatusCode sc;
522 
524  log << MSG::INFO << "Already Initialized!" << endmsg;
525  return StatusCode::SUCCESS;
526  }
528  log << MSG::FATAL << "stop: Invalid state \"" << m_state << "\"" << endmsg;
529  return StatusCode::FAILURE;
530  }
532 
533  // Stop independently managed Algorithms
534  sc = algManager()->stop();
535  if ( !sc.isSuccess() ) return sc;
536 
537  //--------------------------------------------------------------------------
538  // Stop the list of top Services
539  //--------------------------------------------------------------------------
540  sc = svcManager()->stop();
541  if ( !sc.isSuccess() ) return sc;
542 
543  //--------------------------------------------------------------------------
544  // Final steps: Inform user and change internal state
545  //--------------------------------------------------------------------------
546  log << MSG::INFO << "Application Manager Stopped successfully" << endmsg;
548 
549  return sc;
550 }
551 
552 //============================================================================
553 // IAppMgrUI implementation: ApplicationMgr::finalize()
554 //============================================================================
558  log << MSG::INFO << "Already Finalized" << endmsg;
559  return StatusCode::SUCCESS;
560  }
562  log << MSG::FATAL << "finalize: Invalid state \"" << m_state << "\"" << endmsg;
563  return StatusCode::FAILURE;
564  }
566 
567  // disable message suppression in finalize
568  m_svcLocator->service<IProperty>( "MessageSvc" )
569  ->setProperty( Gaudi::Property<bool>( "enableSuppression", false ) )
570  .ignore();
571 
572  // Finalize independently managed Algorithms
573  StatusCode sc = algManager()->finalize();
574  if ( sc.isFailure() ) {
575  log << MSG::WARNING << "Failed to finalize an algorithm." << endmsg;
577  }
578 
579  // Finalize all Services
580  sc = svcManager()->finalize();
581  if ( sc.isFailure() ) {
582  log << MSG::WARNING << "Failed to finalize a service." << endmsg;
584  }
585 
586  // svcManager()->removeService( (IService*) m_processingMgr.get() );
587  // svcManager()->removeService( (IService*) m_runable.get() );
588 
590 
591  if ( sc.isSuccess() ) {
592  log << MSG::INFO << "Application Manager Finalized successfully" << endmsg;
593  } else {
594  log << MSG::ERROR << "Application Manager failed to finalize" << endmsg;
595  }
596 
598  return sc;
599 }
600 
601 //============================================================================
602 // IAppMgrUI implementation: ApplicationMgr::terminate()
603 //============================================================================
606 
608  log << MSG::INFO << "Already Offline" << endmsg;
609  return StatusCode::SUCCESS;
610  }
612  log << MSG::FATAL << "terminate: Invalid state \"" << m_state << "\"" << endmsg;
613  return StatusCode::FAILURE;
614  }
615  // release all Services
617 
618  if ( m_returnCode.value() == Gaudi::ReturnCode::Success ) {
619  log << MSG::INFO << "Application Manager Terminated successfully" << endmsg;
620  } else if ( m_returnCode.value() == Gaudi::ReturnCode::ScheduledStop ) {
621  log << MSG::INFO << "Application Manager Terminated successfully with a user requested ScheduledStop" << endmsg;
622  } else {
623  log << MSG::ERROR << "Application Manager Terminated with error code " << m_returnCode.value() << endmsg;
624  }
625 
626  { // Force a disable the auditing of finalize for MessageSvc
627  auto prop = m_messageSvc.as<IProperty>();
628  if ( prop ) { prop->setProperty( Gaudi::Property<bool>( "AuditFinalize", false ) ).ignore(); }
629  }
630  { // Force a disable the auditing of finalize for JobOptionsSvc
631  auto prop = m_jobOptionsSvc.as<IProperty>();
632  if ( prop ) { prop->setProperty( Gaudi::Property<bool>( "AuditFinalize", false ) ).ignore(); }
633  }
634 
635  // finalize MessageSvc
636  auto svc = m_messageSvc.as<IService>();
637  if ( !svc ) {
638  log << MSG::ERROR << "Could not get the IService interface of the MessageSvc" << endmsg;
639  } else {
640  svc->sysFinalize().ignore();
641  }
642 
643  // finalize JobOptionsSvc
644  svc = m_jobOptionsSvc.as<IService>();
645  if ( !svc ) {
646  log << MSG::ERROR << "Could not get the IService interface of the JobOptionsSvc" << endmsg;
647  } else {
648  svc->sysFinalize().ignore();
649  }
650 
652  return StatusCode::SUCCESS;
653 }
654 
655 //============================================================================
656 // Reach the required state going through all the needed transitions
657 //============================================================================
660 
661  switch ( state ) {
662 
664  switch ( m_state ) {
666  return StatusCode::SUCCESS;
667  break;
669  return terminate();
670  break;
671  default: // Gaudi::StateMachine::INITIALIZED or Gaudi::StateMachine::RUNNING
673  if ( sc.isSuccess() ) { return terminate(); }
674  break;
675  }
676  break;
677 
679  switch ( m_state ) {
681  return StatusCode::SUCCESS;
682  break;
684  return configure();
685  break;
687  return finalize();
688  break;
689  default: // Gaudi::StateMachine::RUNNING
691  if ( sc.isSuccess() ) { return finalize(); }
692  break;
693  }
694  break;
695 
697  switch ( m_state ) {
699  return StatusCode::SUCCESS;
700  break;
702  return initialize();
703  break;
705  return stop();
706  break;
707  default: // Gaudi::StateMachine::OFFLINE
709  if ( sc.isSuccess() ) { return initialize(); }
710  break;
711  }
712  break;
713 
715  switch ( m_state ) {
717  return StatusCode::SUCCESS;
718  break;
720  return start();
721  break;
722  default: // Gaudi::StateMachine::OFFLINE or Gaudi::StateMachine::CONFIGURED
724  if ( sc.isSuccess() ) { return start(); }
725  break;
726  }
727  break;
728  }
729 
730  // If I get here, there has been a problem in the recursion
731 
732  if ( ignoreFailures ) {
733  // force the new state
734  m_state = state;
735  return StatusCode::SUCCESS;
736  }
737 
738  return sc;
739 }
740 
741 //============================================================================
742 // IAppMgrUI implementation: ApplicationMgr::run()
743 //============================================================================
746 
748  if ( sc.isSuccess() ) {
750  if ( m_runable != 0 ) { // loop over the events
751  sc = m_runable->run();
752  if ( !sc.isSuccess() ) { log << MSG::FATAL << "Application execution failed. Ending the job." << endmsg; }
753  } else {
754  log << MSG::FATAL << "Application has no runable object. Check option:" << m_runableType.name() << endmsg;
755  }
756  }
757  if ( sc.isSuccess() ) { // try to close cleanly
759  }
760  // either the runable failed of the stut-down
761  if ( sc.isFailure() ) { // try to close anyway (but keep the StatusCode unchanged)
763  }
764  return sc;
765 }
766 
767 //============================================================================
768 // IEventProcessor implementation: executeEvent(void* par)
769 //============================================================================
773  if ( m_processingMgr ) { return m_processingMgr->executeEvent( par ); }
774  }
775  log << MSG::FATAL << "executeEvent: Invalid state \"" << FSMState() << "\"" << endmsg;
776  return StatusCode::FAILURE;
777 }
778 
779 //============================================================================
780 // IEventProcessor implementation: executeRun(int)
781 //============================================================================
785  if ( m_processingMgr ) { return m_processingMgr->executeRun( evtmax ); }
786  log << MSG::WARNING << "No EventLoop Manager specified " << endmsg;
787  return StatusCode::SUCCESS;
788  }
789  log << MSG::FATAL << "executeRun: Invalid state \"" << FSMState() << "\"" << endmsg;
790  return StatusCode::FAILURE;
791 }
792 
793 //============================================================================
794 // IEventProcessor implementation: stopRun(int)
795 //============================================================================
799  if ( m_processingMgr ) { return m_processingMgr->stopRun(); }
800  log << MSG::WARNING << "No EventLoop Manager specified " << endmsg;
801  return StatusCode::SUCCESS;
802  }
803  log << MSG::FATAL << "stopRun: Invalid state \"" << FSMState() << "\"" << endmsg;
804  return StatusCode::FAILURE;
805 }
806 // Implementation of IAppMgrUI::name
807 const std::string& ApplicationMgr::name() const { return m_name; }
808 
809 // implementation of IService::state
811 // implementation of IService::state
813 
814 //============================================================================
815 // implementation of IService::reinitilaize
816 //============================================================================
819  StatusCode sc;
821  throw GaudiException( "Cannot reinitialize application if not INITIALIZED or RUNNING",
822  "ApplicationMgr::reinitialize", StatusCode::FAILURE );
823  }
825  sc = svcManager()->reinitialize();
826  if ( sc.isFailure() ) retval = sc;
827  sc = algManager()->reinitialize();
828  if ( sc.isFailure() ) retval = sc;
829  return retval;
830 }
831 
832 //============================================================================
833 // implementation of IService::reinitiaize
834 //============================================================================
837  StatusCode sc;
839  throw GaudiException( "Cannot restart application if not RUNNING", "ApplicationMgr::restart", StatusCode::FAILURE );
840  }
841  sc = svcManager()->restart();
842  if ( sc.isFailure() ) retval = sc;
843  sc = algManager()->restart();
844  if ( sc.isFailure() ) retval = sc;
845  return retval;
846 }
847 
848 //============================================================================
849 // Handle properties of the event loop manager (Top alg/Output stream list)
850 //============================================================================
852  if ( m_processingMgr ) {
853  auto props = m_processingMgr.as<IProperty>();
854  if ( props ) props->setProperty( p ).ignore();
855  }
856 }
857 
858 //============================================================================
859 // External Service List handler
860 //============================================================================
862  if ( !( decodeCreateSvcNameList() ).isSuccess() ) {
863  throw GaudiException( "Failed to create ext services", "MinimalEventLoopMgr::createSvcNameListHandler",
865  }
866 }
867 //============================================================================
868 // decodeCreateSvcNameList
869 //============================================================================
872  const auto& theNames = m_createSvcNameList.value();
873  auto it = theNames.begin();
874  auto et = theNames.end();
875  while ( result.isSuccess() && it != et ) {
876  Gaudi::Utils::TypeNameString item( *it++ );
877  if ( ( result = svcManager()->addService( item, ServiceManager::DEFAULT_SVC_PRIORITY ) ).isFailure() ) {
879  log << MSG::ERROR << "decodeCreateSvcNameList: Cannot create service " << item.type() << "/" << item.name()
880  << endmsg;
881  } else {
882  ON_DEBUG {
884  log << MSG::DEBUG << "decodeCreateSvcNameList: Created service " << item.type() << "/" << item.name() << endmsg;
885  }
886  }
887  }
888  return result;
889 }
890 
891 //============================================================================
892 // External Service List handler
893 //============================================================================
895  if ( !( decodeExtSvcNameList() ).isSuccess() ) {
896  throw GaudiException( "Failed to declare ext services", "MinimalEventLoopMgr::extSvcNameListHandler",
898  }
899 }
900 
901 //============================================================================
902 // decodeExtSvcNameList
903 //============================================================================
906 
907  const auto& theNames = m_extSvcNameList.value();
908 
909  auto it = theNames.begin();
910  auto et = theNames.end();
911  while ( result.isSuccess() && it != et ) {
912  Gaudi::Utils::TypeNameString item( *it++ );
913  if ( m_extSvcCreates ) {
914  if ( ( result = svcManager()->addService( item, ServiceManager::DEFAULT_SVC_PRIORITY ) ).isFailure() ) {
916  log << MSG::ERROR << "decodeExtSvcNameList: Cannot create service " << item.type() << "/" << item.name()
917  << endmsg;
918  }
919  } else {
920  if ( ( result = svcManager()->declareSvcType( item.name(), item.type() ) ).isFailure() ) {
922  log << MSG::ERROR << "decodeExtSvcNameList: Cannot declare service " << item.type() << "/" << item.name()
923  << endmsg;
924  }
925  }
926  }
927  return result;
928 }
929 
930 //============================================================================
931 // Dll List handler
932 //============================================================================
934  if ( !( decodeDllNameList() ).isSuccess() ) {
935  throw GaudiException( "Failed to load DLLs.", "MinimalEventLoopMgr::dllNameListHandler", StatusCode::FAILURE );
936  }
937 }
938 
939 //============================================================================
940 // decodeDllNameList
941 //============================================================================
943 
946 
947  // Clean up multiple entries from DLL list
948  // -------------------------------------------------------------------------
949  std::vector<std::string> newList;
950  std::map<std::string, unsigned int> dllInList, duplicateList;
951  {
952  for ( const auto it : m_dllNameList ) {
953  if ( 0 == dllInList[it] ) {
954  newList.push_back( it ); // first instance of this module
955  } else {
956  ++duplicateList[it];
957  } // module listed multiple times
958  ++dllInList[it]; // increment count for this module
959  }
960  }
961  // m_dllNameList = newList; // update primary list to new, filtered list (do not use the
962  // property itself otherwise we get called again infinitely)
963  // List modules that were in there twice..
964  ON_DEBUG if ( !duplicateList.empty() ) {
965  log << MSG::DEBUG << "Removed duplicate entries for modules : ";
966  for ( auto it = duplicateList.begin(); it != duplicateList.end(); ++it ) {
967  log << it->first << "(" << 1 + it->second << ")";
968  if ( it != --duplicateList.end() ) log << ", ";
969  }
970  log << endmsg;
971  }
972  // -------------------------------------------------------------------------
973 
974  const std::vector<std::string>& theNames = newList;
975 
976  // only load the new dlls or previously failed dlls
977  ON_DEBUG log << MSG::DEBUG << "Loading declared DLL's" << endmsg;
978 
979  std::vector<std::string> successNames, failNames;
980  for ( const auto& it : theNames ) {
981  if ( std::find( m_okDlls.rbegin(), m_okDlls.rend(), it ) == m_okDlls.rend() ) {
982  // found a new module name
983  StatusCode status = m_classManager->loadModule( it );
984  if ( status.isFailure() ) {
985  failNames.push_back( it );
986  result = StatusCode::FAILURE;
987  } else {
988  successNames.push_back( it );
989  }
990  }
991  }
992 
993  // report back to the user and store the names of the succesfully loaded dlls
994  if ( !successNames.empty() ) {
995  log << MSG::INFO << "Successfully loaded modules : ";
996  for ( auto it = successNames.begin(); it != successNames.end(); it++ ) {
997  log << ( *it );
998  if ( ( it + 1 ) != successNames.end() ) log << ", ";
999  // save name
1000  m_okDlls.push_back( *it );
1001  }
1002  log << endmsg;
1003  }
1004 
1005  if ( result == StatusCode::FAILURE ) {
1006  log << MSG::WARNING << "Failed to load modules: ";
1007  for ( auto it = failNames.begin(); it != failNames.end(); it++ ) {
1008  log << ( *it );
1009  if ( ( it + 1 ) != failNames.end() ) log << ", ";
1010  }
1011  log << endmsg;
1012  }
1013  return result;
1014 }
1015 
1017  resetMessaging();
1018  for ( auto& mgrItem : m_managers ) { mgrItem.second->outputLevelUpdate(); }
1019 }
The ServiceManager class is in charge of the creation of concrete instances of Services.
Gaudi::StateMachine::State m_targetState
Internal State.
GAUDI_API std::string getEnv(const char *var)
get a particular environment variable (returning "UNKNOWN" if not set)
Definition: System.cpp:380
The AlgorithmManager class is in charge of the creation of concrete instances of Algorithms.
StatusCode initialize() override
constexpr int FinalizationFailure
Error codes for operation failures.
Definition: AppReturnCode.h:32
#define UNLIKELY(x)
Definition: Kernel.h:89
virtual StatusCode addService(IService *svc, int prio=DEFAULT_SVC_PRIORITY)=0
Add a service to the "active" list of services of the factory.
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
Gaudi::Property< bool > m_propertiesPrint
virtual StatusCode stopRun()=0
Schedule a stop of the current event processing.
T empty(T...args)
virtual StatusCode run()=0
Run the class implementation.
Define general base for Gaudi exception.
StatusCode decodeDllNameList()
Gaudi::Property< int > m_returnCode
Property to record the error conditions occurring during the running.
GAUDI_API int setEnv(const std::string &name, const std::string &value, int overwrite=1)
Set an environment variables.
Definition: System.cpp:494
Gaudi::Property< bool > m_stopOnSignal
Property to enable/disable the "stop on signal" service.
StatusCode loadModule(const std::string &module, bool fireIncident=true) override
Gaudi::Property< bool > m_codeCheck
SmartIF< IRunable > m_runable
Reference to the runable object.
Implementation of property with value of concrete type.
Definition: Property.h:352
StatusCode setProperty(const Gaudi::Details::PropertyBase &p) override
set the property form another property
const std::vector< Gaudi::Details::PropertyBase * > & getProperties() const override
get all properties
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:309
T rend(T...args)
ManagersMap m_managers
Map of known component managers.
Gaudi::Property< std::string > m_jobOptionsType
bool isSuccess() const
Definition: StatusCode.h:267
const std::string & name() const override
T endl(T...args)
static Time current()
Returns the current time.
Definition: Time.cpp:109
Gaudi::Property< std::map< std::string, std::string > > m_environment
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
void outputLevelUpdate() override
Function to call to update the outputLevel of the components (after a change in MessageSvc).
virtual StatusCode executeEvent(void *par=0)=0
Process single event.
Gaudi::Property< std::string > m_appVersion
T end(T...args)
static GAUDI_API void enableChecking()
Definition: StatusCode.cpp:42
std::vector< std::string > m_okDlls
names of successfully loaded dlls
State
Allowed states for classes implementing the state machine (ApplicationMgr, Algorithm, Service, AlgTool).
Definition: StateMachine.h:12
StatusCode nextEvent(int maxevt) override
SmartIF< IJobOptionsSvc > m_jobOptionsSvc
Reference to JobOption service.
AlgTypeAliasesMap & typeAliases()
void createSvcNameListHandler(Gaudi::Details::PropertyBase &)
bool isFailure() const
Definition: StatusCode.h:130
SmartIF< IEventProcessor > m_processingMgr
Reference to processing manager object.
StatusCode terminate() override
SmartIF< ISvcManager > & svcManager()
virtual StatusCode start()=0
Start (from INITIALIZED to RUNNING).
constexpr int ScheduledStop
Definition: AppReturnCode.h:25
Gaudi::Property< std::string > m_eventLoopMgr
STL class.
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:76
virtual StatusCode nextEvent(int maxevt)=0
Process the next maxevt events.
void evtLoopPropertyHandler(Gaudi::Details::PropertyBase &theProp)
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:76
T push_back(T...args)
Interface ID class.
Definition: IInterface.h:29
virtual StatusCode setProperty(const Gaudi::Details::PropertyBase &p)=0
Set the property by property.
Gaudi::Property< int > m_outputLevel
SmartIF< IFace > as() const
return a new SmartIF instance to another interface
Definition: SmartIF.h:107
Helper class to parse a string of format "type/name".
StatusCode executeRun(int evtmax) override
implementation of IEventProcessor::executeRun(int)
virtual StatusCode stop()=0
Stop (from RUNNING to INITIALIZED).
virtual StatusCode reinitialize()=0
Initialization (from INITIALIZED or RUNNING to INITIALIZED, via CONFIGURED).
Gaudi::StateMachine::State targetFSMState() const override
void extSvcNameListHandler(Gaudi::Details::PropertyBase &theProp)
General service interface definition.
Definition: IService.h:18
#define ON_DEBUG
SmartIF< ISvcLocator > m_svcLocator
Reference to its own service locator (must be instantiated prior to any service!) ...
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
virtual SmartIF< IService > & createService(const Gaudi::Utils::TypeNameString &nametype)=0
Creates and instance of a service type that has been declared beforehand and assigns it a name...
Gaudi::Details::PropertyBase * declareProperty(const std::string &name, TYPE &value, const std::string &doc="none")
Declare a property (templated)
Definition of the basic interface.
Definition: IInterface.h:244
virtual StatusCode setMyProperties(const std::string &client, IProperty *me)=0
Override default properties of the calling client.
Gaudi::Property< std::vector< std::string > > m_extSvcNameList
#define DECLARE_OBJECT_FACTORY(x)
Definition: ObjectFactory.h:15
void dllNameListHandler(Gaudi::Details::PropertyBase &theProp)
Gaudi::Property< std::string > m_runableType
Gaudi::Property< bool > m_stalledEventMonitoring
Property to enable/disable the monitoring and reporting of stalled events.
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
Definition: Property.h:32
StatusCode GoToState(Gaudi::StateMachine::State state, bool ignoreFailures=false)
Reach a state from current state (whichever it is) going through the correct transitions.
StatusCode finalize() override
Gaudi::Property< std::vector< std::string > > m_svcOptMapping
virtual StatusCode initialize()=0
Initialization (from CONFIGURED to INITIALIZED).
Gaudi::Property< std::string > m_jobOptionsPreAction
Gaudi::Property< std::vector< std::string > > m_svcMapping
Gaudi::Property< std::vector< std::string > > m_dllNameList
GAUDI_API bool isEnvSet(const char *var)
Check if an environment variable is set or not.
Definition: System.cpp:400
StatusCode queryInterface(const InterfaceID &iid, void **pinterface) override
implementation of IInterface::queryInterface
StatusCode executeEvent(void *par) override
implementation of IEventProcessor::executeEvent(void*)
The Application Manager class.
Gaudi::Property< bool > m_actHistory
constexpr bool versionMatch(const InterfaceID &iid) const
check compatibility.
Definition: IInterface.h:55
StatusCode queryInterface(const InterfaceID &iid, void **pinterface) override
StatusCode decodeExtSvcNameList()
T find(T...args)
GAUDI_API const std::string & hostName()
Host name.
Definition: System.cpp:314
Gaudi::Property< bool > m_extSvcCreates
SmartIF< DLLClassManager > m_classManager
Reference to the class manager.
Gaudi::Property< std::string > m_jobOptionsSvcType
StatusCode start() override
Gaudi::Property< std::vector< std::string > > m_createSvcNameList
StatusCode restart() override
StatusCode configure() override
T begin(T...args)
virtual StatusCode restart()=0
Initialization (from RUNNING to RUNNING, via INITIALIZED).
StatusCode stopRun() override
implementation of IEventProcessor::stopRun()
const std::string & type() const
StatusCode decodeCreateSvcNameList()
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:153
virtual StatusCode finalize()=0
Finalize (from INITIALIZED to CONFIGURED).
Gaudi::Property< std::string > m_jobOptionsPostAction
T c_str(T...args)
constexpr static const auto FAILURE
Definition: StatusCode.h:86
StatusCode i_startup()
Internal startup routine.
StatusCode stop() override
std::string m_name
Name.
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
static GAUDI_API void disableChecking()
Definition: StatusCode.cpp:44
Gaudi::Property< std::string > m_messageSvcType
#define ON_VERBOSE
StatusCode reinitialize() override
MSG::Level level() const
Retrieve output level.
Definition: MsgStream.h:103
Gaudi::StateMachine::State m_state
Internal State.
Gaudi::Property< std::string > m_appName
Gaudi::StateMachine::State FSMState() const override
const std::string & name() const
SmartIF< ISvcLocator > & serviceLocator() const override
Needed to locate the message service.
virtual StatusCode executeRun(int maxevt)=0
Process the maxevt events as a Run.
int maxevt
Definition: Bootstrap.cpp:260
constexpr int Success
Definition: AppReturnCode.h:16
StatusCode run() override
StatusCode queryInterface(const InterfaceID &iid, void **pinterface) override
The IProperty is the basic interface for all components which have properties that can be set or get...
Definition: IProperty.h:20
SmartIF< IAlgManager > & algManager()
static const InterfaceID & interfaceID()
Return an instance of InterfaceID identifying the interface.
Definition: IInterface.h:253
SmartIF< IMessageSvc > m_messageSvc
Reference to the message service.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192
Gaudi::Property< std::string > m_jobOptionsPath
virtual void setOutputLevel(int new_level)=0
Set new global output level threshold.
std::string format(bool local, std::string spec="%c") const
Format the time using strftime.
Definition: Time.cpp:252
virtual StatusCode queryInterface(const InterfaceID &ti, void **pp)=0
Set the void** to the pointer to the requested interface of the instance.
T rbegin(T...args)