| # Gaudi Framework, version v20r3
Generated: 24 Nov 2008

# ApplicationMgr.cpp

Go to the documentation of this file.

    00001 // $Id: ApplicationMgr.cpp,v 1.77 2008/11/10 15:29:09 marcocle Exp $
    00002
    00003 // Include files
    00004 #include "ApplicationMgr.h"
    00005 #include "ServiceManager.h"
    00006 #include "AlgorithmManager.h"
    00007 #include "DLLClassManager.h"
    00008
    00009 #include "GaudiKernel/ListItem.h"
    00010 #include "GaudiKernel/IService.h"
    00011 #include "GaudiKernel/IRunable.h"
    00012 #include "GaudiKernel/IMessageSvc.h"
    00013 #include "GaudiKernel/IJobOptionsSvc.h"
    00014
    00015 #include "GaudiKernel/SmartIF.h"
    00016 #include "GaudiKernel/MsgStream.h"
    00017 #include "GaudiKernel/PropertyMgr.h"
    00018 #include "GaudiKernel/ObjectFactory.h"
    00019
    00020 #include "GaudiKernel/GaudiException.h"
    00021 #include "GaudiKernel/ThreadGaudi.h"
    00022
    00023 #include "GaudiKernel/StatusCode.h"
    00024
    00025 #include <algorithm>
    00026 #include <cassert>
    00027 #include <ctime>
    00028 #include <limits>
    00029
    00030 DECLARE_OBJECT_FACTORY(ApplicationMgr)
    00031
    00032 static const char* s_eventloop = "EventLoop";
    00033 static const char* s_runable   = "Runable";
    00034
    00035
    00036 // Implementation class for the Application Manager. In this way the
    00037 // ApplicationMgr class is a fully insulated concrete class. Clients
    00038 // (main programs) will not need to re-compile if there are changes
    00039 // in the implementation
    00040
    00041 //=======================================================================
    00042 // Constructor
    00043 //=======================================================================
    00044 ApplicationMgr::ApplicationMgr(IInterface*) {
    00045   // IInterface initialization
    00046   m_refcount = 1;
    00047
    00048   // Initialize two basic services: messagesvc & joboptions
    00049   m_messageSvc        = 0;
    00050   m_jobOptionsSvc     = 0;
    00051   // Service Locator/Factory has to be instantiated FIRST!!!!!
    00052   // as subsequent internal services need access to SvcLocator/Factory obj
    00053   m_svcManager        = new ServiceManager(this);
    00054   m_svcLocator        = m_svcManager; // alias to distinguish dual function
    00055
    00056   // Instanciate internal services
    00057   // SvcLocator/Factory HAS to be already instantiated
    00058   m_algManager   = new AlgorithmManager(this);
    00059   m_classManager = new DLLClassManager(this);
    00060   m_propertyMgr  = new PropertyMgr(this);
    00061
    00062   m_name  = "ApplicationMgr";
    00063   m_state = Gaudi::StateMachine::OFFLINE;
    00064   m_targetState = Gaudi::StateMachine::OFFLINE;
    00065
    00066   m_propertyMgr->declareProperty("Go",            m_SIGo = 0 );
    00067   m_propertyMgr->declareProperty("Exit",          m_SIExit = 0 );
    00068   m_propertyMgr->declareProperty("Dlls",          m_dllNameList );
    00069   m_propertyMgr->declareProperty("ExtSvc",        m_extSvcNameList );
    00070   m_propertyMgr->declareProperty("CreateSvc",     m_createSvcNameList );
    00071   m_propertyMgr->declareProperty("ExtSvcCreates", m_extSvcCreates=true );
    00072
    00073   m_propertyMgr->declareProperty("SvcMapping",    m_svcMapping );
    00074   m_propertyMgr->declareProperty("SvcOptMapping", m_svcOptMapping );
    00075
    00076   m_propertyMgr->declareProperty("TopAlg",        m_topAlgNameList );
    00077   m_propertyMgr->declareProperty("OutStream",     m_outStreamNameList );
    00078   m_propertyMgr->declareProperty("OutStreamType", m_outStreamType = "OutputStream" );
    00079   m_propertyMgr->declareProperty("MessageSvcType",m_messageSvcType= "MessageSvc" );
    00080   m_propertyMgr->declareProperty("JobOptionsSvcType",
    00081                                  m_jobOptionsSvcType = "JobOptionsSvc" );
    00082   m_propertyMgr->declareProperty( s_runable,      m_runableType   = "AppMgrRunable");
    00083   m_propertyMgr->declareProperty( s_eventloop,    m_eventLoopMgr  = "EventLoopMgr");
    00084
    00085   m_propertyMgr->declareProperty("HistogramPersistency", m_histPersName="NONE");
    00086
    00087   // Declare Job Options Service properties and set default
    00088   m_propertyMgr->declareProperty("JobOptionsType", m_jobOptionsType = "FILE");
    00089   m_propertyMgr->declareProperty("JobOptionsPath", m_jobOptionsPath = "");
    00090   m_propertyMgr->declareProperty("EvtMax",         m_evtMax = -1);
    00091   m_propertyMgr->declareProperty("EvtSel",         m_evtsel );
    00092   m_propertyMgr->declareProperty("OutputLevel",    m_outputLevel = MSG::INFO);
    00093
    00094   m_propertyMgr->declareProperty("MultiThreadExtSvc", m_multiThreadSvcNameList);
    00095   m_propertyMgr->declareProperty("NoOfThreads",    m_noOfEvtThreads = 0);
    00096   m_propertyMgr->declareProperty("AppName",        m_appName = "ApplicationMgr");
    00097   m_propertyMgr->declareProperty("AppVersion",     m_appVersion = "");
    00098
    00099   m_propertyMgr->declareProperty("AuditTools",      m_auditTools = false);
    00100   m_propertyMgr->declareProperty("AuditServices",   m_auditSvcs = false);
    00101   m_propertyMgr->declareProperty("AuditAlgorithms", m_auditAlgs = false);
    00102
    00103   m_propertyMgr->declareProperty("ActivateHistory", m_actHistory = false);
    00104   m_propertyMgr->declareProperty("StatusCodeCheck", m_codeCheck = false);
    00105
    00106   m_propertyMgr->declareProperty("Environment",    m_environment);
    00107
    00108   // ServiceMgr Initialization loop checking
    00109   m_propertyMgr->declareProperty("InitializationLoopCheck", m_loopCheck = true)
    00110     ->declareUpdateHandler(&ApplicationMgr::initLoopCheckHndlr, this);
    00111   m_svcManager->setLoopCheckEnabled(m_loopCheck);
    00112
    00113   // Flag to activate the printout of properties
    00114   m_propertyMgr->declareProperty
    00115     ( "PropertiesPrint",
    00116       m_propertiesPrint = false,
    00117       "Flag to activate the printout of properties" );
    00118
    00119   m_propertyMgr->declareProperty("ReflexPluginDebugLevel", m_reflexDebugLevel = 0 );
    00120
    00121   // Add action handlers to the appropriate properties
    00122   m_SIGo.declareUpdateHandler  ( &ApplicationMgr::SIGoHandler         , this );
    00123   m_SIExit.declareUpdateHandler( &ApplicationMgr::SIExitHandler       , this );
    00124   m_topAlgNameList.declareUpdateHandler(&ApplicationMgr::evtLoopPropertyHandler, this);
    00125   m_outStreamNameList.declareUpdateHandler(&ApplicationMgr::evtLoopPropertyHandler, this);
    00126   m_outStreamType.declareUpdateHandler(&ApplicationMgr::evtLoopPropertyHandler, this);
    00127   m_reflexDebugLevel.declareUpdateHandler(&ApplicationMgr::reflexDebugPropertyHandler, this);
    00128   m_processingMgr = 0;
    00129   m_runable = 0;
    00130   m_svcMapping.push_back("EvtDataSvc/EventDataSvc");
    00131   m_svcMapping.push_back("DetDataSvc/DetectorDataSvc");
    00132   m_svcMapping.push_back("HistogramSvc/HistogramDataSvc");
    00133   m_svcMapping.push_back("HbookCnv::PersSvc/HbookHistSvc");
    00134   m_svcMapping.push_back("RootHistCnv::PersSvc/RootHistSvc");
    00135   m_svcMapping.push_back("EvtPersistencySvc/EventPersistencySvc");
    00136   m_svcMapping.push_back("DetPersistencySvc/DetectorPersistencySvc");
    00137   m_svcMapping.push_back("HistogramPersistencySvc/HistogramPersistencySvc");
    00138 }
    00139
    00140 //============================================================================
    00141 // destructor
    00142 //============================================================================
    00143 ApplicationMgr::~ApplicationMgr() {
    00144   if( m_algManager ) m_algManager->release();
    00145   if( m_classManager ) m_classManager->release();
    00146   if( m_propertyMgr ) m_propertyMgr->release();
    00147   if( m_messageSvc ) m_messageSvc->release();
    00148   if( m_jobOptionsSvc ) m_jobOptionsSvc->release();
    00149   if( m_svcManager ) m_svcManager->release();  // Need to be the last one!!
    00150 }
    00151
    00152 //============================================================================
    00153 // IInterface implementation: ApplicationMgr::addRef()
    00154 //============================================================================
    00155 unsigned long ApplicationMgr::addRef() {
    00156   m_refcount++;
    00157   return m_refcount;
    00158 }
    00159
    00160 //============================================================================
    00161 // IInterface implementation: ApplicationMgr::release()
    00162 //============================================================================
    00163 unsigned long ApplicationMgr::release() {
    00164   long count = --m_refcount;
    00165   if( count <= 0) {
    00166     delete this;
    00167   }
    00168   return count;
    00169 }
    00170
    00171 //============================================================================
    00172 // IInterface implementation: queryInterface::addRef()
    00173 //============================================================================
    00174 StatusCode ApplicationMgr::queryInterface
    00175 ( const InterfaceID& iid  ,
    00176   void**             ppvi )
    00177 {
    00178   if ( 0 == ppvi ) { return StatusCode::FAILURE ; }
    00179
    00180   // try to find own/direct interfaces:
    00181   if      ( IAppMgrUI       ::interfaceID() . versionMatch ( iid ) )
    00182   { *ppvi = static_cast<IAppMgrUI*>        ( this ) ; }
    00183   else if ( IEventProcessor ::interfaceID() .versionMatch  ( iid ) )
    00184   { *ppvi = static_cast<IEventProcessor*>  ( this ) ; }
    00185   else if ( IService        ::interfaceID() . versionMatch ( iid ) )
    00186   { *ppvi = static_cast<IService*>         ( this ) ; }
    00187   else if ( INamedInterface ::interfaceID() . versionMatch ( iid ) )
    00188   { *ppvi = static_cast<INamedInterface*>  ( this ) ; }
    00189   else if ( IStateful       ::interfaceID() . versionMatch ( iid ) )
    00190   { *ppvi = static_cast<IStateful*>        ( this ) ; }
    00191   else if ( IInterface      ::interfaceID() . versionMatch ( iid ) )
    00192   { *ppvi = static_cast<IInterface*>       ( this ) ; }
    00193   // find indirect interfaces :
    00194   else if ( ISvcLocator     ::interfaceID() . versionMatch ( iid ) )
    00195   { return m_svcLocator   -> queryInterface ( iid , ppvi ) ; }
    00196   else if ( ISvcManager     ::interfaceID() . versionMatch ( iid ) )
    00197   { return m_svcManager   -> queryInterface ( iid , ppvi ) ; }
    00198   else if ( IAlgManager     ::interfaceID() . versionMatch ( iid ) )
    00199   { return m_algManager   -> queryInterface ( iid , ppvi ) ; }
    00200   else if ( IClassManager   ::interfaceID() . versionMatch ( iid ) )
    00201   { return m_classManager -> queryInterface ( iid , ppvi ) ; }
    00202   else if ( IProperty       ::interfaceID() . versionMatch ( iid ) )
    00203   { return m_propertyMgr  -> queryInterface ( iid , ppvi ) ; }
    00204   else
    00205   { *ppvi = 0 ; return StatusCode::FAILURE; }              // RETURN
    00206   // increment the reference counter:
    00207   addRef ();
    00208   //
    00209   return StatusCode::SUCCESS ;
    00210 }
    00211
    00212 //============================================================================
    00213 // ApplicationMgr::i_startup()
    00214 //============================================================================
    00215 StatusCode ApplicationMgr::i_startup() {
    00216   MsgStream tlog( m_messageSvc, name() );
    00217   IService   *msgsvc = 0, *jobsvc = 0;
    00218   IProperty* jobOptsIProp = 0;
    00219   IProperty* msgSvcIProp = 0;
    00220   StatusCode  sc;
    00221
    00222   // declare factories in current module
    00223   m_classManager->loadModule("").ignore();
    00224
    00225   // Create the Message service
    00226   sc = m_svcManager->createService( m_messageSvcType, "MessageSvc", msgsvc );
    00227   if( !sc.isSuccess() )  {
    00228     tlog << MSG::FATAL << "Error creating MessageSvc of type "
    00229          << m_messageSvcType << endreq;
    00230     return sc;
    00231   }
    00232   // Create the Job Options service
    00233   sc = m_svcManager->createService( m_jobOptionsSvcType, "JobOptionsSvc", jobsvc );
    00234   if( !sc.isSuccess() )   {
    00235     tlog << MSG::FATAL << "Error creating JobOptionsSvc" << endreq;
    00236     return sc;
    00237   }
    00238
    00239   sc = m_svcLocator->service( "JobOptionsSvc", jobOptsIProp);
    00240   if (  !sc.isSuccess() )   {
    00241     tlog << MSG::FATAL << "Error locating JobOptionsSvc" << endreq;
    00242     return sc;
    00243   }
    00244   sc = jobOptsIProp->setProperty( StringProperty("TYPE", m_jobOptionsType) );
    00245   if( !sc.isSuccess() )   {
    00246     tlog << MSG::FATAL << "Error setting TYPE option in JobOptionsSvc"
    00247          << endreq;
    00248     return sc;
    00249   }
    00250
    00251   if ( m_jobOptionsPath != "") {         // The command line takes precedence
    00252     sc = jobOptsIProp->setProperty( StringProperty("PATH", m_jobOptionsPath) );
    00253     if( !sc.isSuccess() )   {
    00254       tlog << MSG::FATAL << "Error setting PATH option in JobOptionsSvc"
    00255            << endreq;
    00256       return sc;
    00257     }
    00258   }
    00259   else if ( 0 != getenv("JOBOPTPATH") ) {// Otherwise the Environment JOBOPTPATH
    00260     sc = jobOptsIProp->setProperty (StringProperty("PATH",
    00261                                                    getenv("JOBOPTPATH")));
    00262     if( !sc.isSuccess() )   {
    00263       tlog << MSG::FATAL
    00264            << "Error setting PATH option in JobOptionsSvc from env"
    00265            << endreq;
    00266       return sc;
    00267     }
    00268   }
    00269   else {                                   // Otherwise the default
    00270     sc = jobOptsIProp->setProperty (StringProperty("PATH",
    00271                                                    "../options/job.opts"));
    00272     if( !sc.isSuccess() )   {
    00273       tlog << MSG::FATAL
    00274            << "Error setting PATH option in JobOptionsSvc to default"
    00275            << endreq;
    00276       return sc;
    00277     }
    00278   }
    00279   jobOptsIProp->release();
    00280
    00281   // Sets my default the Output Level of the Message service to be
    00282   // the same as this
    00283   m_svcLocator->service( "MessageSvc", msgSvcIProp).ignore();
    00284   msgSvcIProp->setProperty( IntegerProperty("OutputLevel", m_outputLevel)).ignore();
    00285   msgSvcIProp->release();
    00286
    00287   sc = jobsvc->sysInitialize();
    00288   if( !sc.isSuccess() )   {
    00289     tlog << MSG::FATAL << "Error initializing JobOptionsSvc" << endreq;
    00290     return sc;
    00291   }
    00292   sc = msgsvc->sysInitialize();
    00293   if( !sc.isSuccess() )  {
    00294     tlog << MSG::FATAL << "Error initializing MessageSvc" << endreq;
    00295     return sc;
    00296   }
    00297
    00298   // Get the useful interface from Message anf JobOptions services
    00299   sc = m_svcLocator->service( "MessageSvc", m_messageSvc);
    00300   if( !sc.isSuccess() )  {
    00301     tlog << MSG::FATAL << "Error retrieving MessageSvc." << endreq;
    00302     return sc;
    00303   }
    00304   sc = m_svcLocator->service( "JobOptionsSvc", m_jobOptionsSvc);
    00305   if( !sc.isSuccess() )  {
    00306     tlog << MSG::FATAL << "Error retrieving JobOptionsSvc." << endreq;
    00307     return sc;
    00308   }
    00309   jobsvc->release();
    00310   msgsvc->release();
    00311
    00312   return sc;
    00313 }
    00314
    00315 //============================================================================
    00316 // IAppMgrUI implementation: ApplicationMgr::configure()
    00317 //============================================================================
    00318 StatusCode ApplicationMgr::configure() {
    00319   // Check if the state is compatible with the transition
    00320   MsgStream tlog( m_messageSvc, name() );
    00321   if( Gaudi::StateMachine::CONFIGURED == m_state ) {
    00322     tlog << MSG::INFO << "Already Configured" << endreq;
    00323     return StatusCode::SUCCESS;
    00324   }
    00325   else if( Gaudi::StateMachine::OFFLINE != m_state ) {
    00326     tlog << MSG::FATAL
    00327          << "configure: Invalid state \""  << m_state << "\"" << endreq;
    00328     return StatusCode::FAILURE;
    00329   }
    00330   m_targetState = Gaudi::StateMachine::CONFIGURED;
    00331
    00332   StatusCode  sc;
    00333   sc = i_startup();
    00334   if ( !sc.isSuccess() )    {
    00335     return sc;
    00336   }
    00337
    00338   MsgStream log( m_messageSvc, name() );
    00339
    00340   // Get my own options using the Job options service
    00341   log << MSG::DEBUG << "Getting my own properties" << endreq;
    00342   sc = m_jobOptionsSvc->setMyProperties( name(), m_propertyMgr );
    00343   if( !sc.isSuccess() ) {
    00344     log << MSG::WARNING << "Problems getting my properties from JobOptionsSvc"
    00345         << endreq;
    00346     return sc;
    00347   }
    00348
    00349   // Check current outputLevel to eventually inform the MessageSvc
    00350   if( m_outputLevel != MSG::NIL && !m_appName.empty() ) {
    00351     assert(0 != m_messageSvc);
    00352     m_messageSvc->setOutputLevel( name(), m_outputLevel );
    00353     // Print a welcome message
    00354     log << MSG::ALWAYS
    00355         << std::endl
    00356         << "=================================================================="
    00357         << "=================================================================="
    00358         << std::endl
    00359         << "                                "
    00360         << "                   Welcome to " << m_appName;
    00361
    00362     if( "" != m_appVersion ) {
    00363       log << MSG::ALWAYS << " version " << m_appVersion;
    00364     }
    00365     else {
    00366       log << MSG::ALWAYS << " $Revision: 1.77 $";
    00367     }
    00368
    00369     // Add the host name and current time to the message
    00370     time_t t;
    00371     std::time( &t );
    00372     tm* localt = std::localtime( &t );
    00373
    00374     log << MSG::ALWAYS
    00375         << std::endl
    00376         << "                                "
    00377         << "          running on " << System::hostName()
    00378         << " on " << std::asctime( localt )
    00379         << "=================================================================="
    00380         << "=================================================================="
    00381         << endmsg;
    00382   }
    00383
    00384   // print all own properties if the options "PropertiesPrint" is set to true
    00385   if ( m_propertiesPrint )
    00386   {
    00387     typedef std::vector<Property*> Properties;
    00388     const Properties& properties = m_propertyMgr->getProperties() ;
    00389     log << MSG::ALWAYS
    00390         << "List of ALL properties of "
    00391         << System::typeinfoName ( typeid( *this ) ) << "/" << this->name()
    00392         << "  #properties = " << properties.size() << endreq ;
    00393     for ( Properties::const_iterator property = properties.begin() ;
    00394           properties.end() != property ; ++property )
    00395     { log << "Property ['Name': Value] = " << ( **property) << endreq ; }
    00396   }
    00397
    00398   // Check if StatusCode need to be checked
    00399   if (m_codeCheck) {
    00400     StatusCode::enableChecking();
    00401     sc = addMultiSvc("StatusCodeSvc", "StatusCodeSvc", -9999);
    00402     if ( sc.isFailure() ) {
    00403       log << MSG::FATAL << "Error adding StatusCodeSvc for multiple threads" << endreq;
    00404       return StatusCode::FAILURE;
    00405     }
    00406   } else {
    00407     StatusCode::disableChecking();
    00408   }
    00409
    00410   // set the requested environment variables
    00411   std::map<std::string,std::string>::iterator var;
    00412   for ( var = m_environment.begin(); var != m_environment.end(); ++var ) {
    00413     const std::string &name  = var->first;
    00414     const std::string &value = var->second;
    00415     std::string old = System::getEnv(name.c_str());
    00416     if ( !old.empty() && (old != "UNKNOWN" )) {
    00417       log << MSG::WARNING;
    00418     }
    00419     else {
    00420       log << MSG::DEBUG;
    00421     }
    00422     log << "Setting " << name << " = " << value << endmsg;
    00423     System::setEnv(name,value);
    00424   }
    00425
    00426   //Declare Service Types
    00427   VectorName::const_iterator j;
    00428   for(j=m_svcMapping.begin(); j != m_svcMapping.end(); ++j)  {
    00429     ListItem itm(*j);
    00430     if ( declareMultiSvcType(itm.name(), itm.type()).isFailure() )  {
    00431       log << MSG::ERROR << "configure: declaring svc type:'" << *j << "' failed." << endmsg;
    00432       return StatusCode::FAILURE;
    00433     }
    00434   }
    00435   for(j=m_svcOptMapping.begin(); j != m_svcOptMapping.end(); ++j)  {
    00436     ListItem itm(*j);
    00437     if ( declareMultiSvcType(itm.name(), itm.type()).isFailure() )  {
    00438       log << MSG::ERROR << "configure: declaring svc type:'" << *j << "' failed." << endmsg;
    00439       return StatusCode::FAILURE;
    00440     }
    00441   }
    00442
    00443   //--------------------------------------------------------------------------
    00444   // Declare other Services and Algorithms by loading DLL's
    00445   sc = decodeDllNameList( );
    00446   if ( sc.isFailure( ) ) {
    00447     log << MSG::ERROR << "Failure loading declared DLL's" << endreq;
    00448     return sc;
    00449   }
    00450
    00451   //--------------------------------------------------------------------------
    00452   // Deal with the services explicitely declared by the user.
    00453   sc = decodeExtSvcNameList();
    00454   if ( sc.isFailure( ) ) {
    00455     log << MSG::ERROR << "Failure during external service association" << endreq;
    00456     return sc;
    00457   }
    00458
    00459   sc = decodeMultiThreadSvcNameList( );
    00460   if ( sc.isFailure( ) ) {
    00461     log << MSG::ERROR << "Failure during multi thread service creation"
    00462         << endreq;
    00463     return sc;
    00464   }
    00465
    00466   sc = decodeCreateSvcNameList();
    00467   if ( sc.isFailure( ) ) {
    00468     log << MSG::ERROR << "Failure during external service creation" << endreq;
    00469     return sc;
    00470   }
    00471
    00472
    00473   //--------------------------------------------------------------------------
    00474   // Retrieve intrinsic services. If needed configure them.
    00475   //--------------------------------------------------------------------------
    00476   ListItem evtloop_item(m_eventLoopMgr);
    00477   sc = addMultiSvc(evtloop_item.type(), evtloop_item.name(), 100);
    00478   if( !sc.isSuccess() )  {
    00479     log << MSG::FATAL << "Error adding :" << m_eventLoopMgr << endreq;
    00480     return sc;
    00481   }
    00482
    00483   if (m_noOfEvtThreads == 0) {
    00484     sc = m_svcLocator->service(m_runableType, m_runable);
    00485     if( !sc.isSuccess() )  {
    00486       log << MSG::FATAL
    00487           << "Error retrieving Runable:" << m_runableType
    00488           << "\n Check option ApplicationMgr." << s_runable << endreq;
    00489       return sc;
    00490     }
    00491     sc = m_svcLocator->service( evtloop_item.name(), m_processingMgr);
    00492     if( !sc.isSuccess() )  {
    00493       log << MSG::FATAL
    00494           << "Error retrieving Processing manager:" << m_eventLoopMgr
    00495           << "\n Check option ApplicationMgr." << s_eventloop
    00496           << "\n No events will be processed." << endreq;
    00497       return sc;
    00498     }
    00499   }
    00500
    00501   // Establish Update Handlers for ExtSvc and DLLs Properties
    00502   m_extSvcNameList.declareUpdateHandler (&ApplicationMgr::extSvcNameListHandler,
    00503                                          this);
    00504   m_createSvcNameList.declareUpdateHandler (&ApplicationMgr::createSvcNameListHandler,
    00505                                          this);
    00506   m_multiThreadSvcNameList.declareUpdateHandler
    00507     (&ApplicationMgr::multiThreadSvcNameListHandler, this);
    00508   m_dllNameList.declareUpdateHandler (&ApplicationMgr::dllNameListHandler,
    00509                                       this );
    00510
    00511   if (m_actHistory) {
    00512     // Create HistorySvc with a priority to ensure it's initialized last, finalized first
    00513     sc = m_svcManager->addService("HistorySvc","HistorySvc",std::numeric_limits<int>::max());
    00514     if ( sc.isFailure() ) {
    00515       log << MSG::FATAL << "Error adding HistorySvc" << endreq;
    00516       return StatusCode::FAILURE;
    00517     }
    00518
    00519     if (m_noOfEvtThreads > 0) {
    00520       sc = addMultiSvc("HistorySvc","HistorySvc",std::numeric_limits<int>::max());
    00521       if ( sc.isFailure() ) {
    00522         log << MSG::FATAL << "Error adding HistorySvc for multiple threads"
    00523             << endreq;
    00524         return StatusCode::FAILURE;
    00525       }
    00526     }
    00527   }
    00528
    00529   log << MSG::INFO << "Application Manager Configured successfully" << endreq;
    00530   m_state = m_targetState;
    00531   return StatusCode::SUCCESS;
    00532 }
    00533
    00534 //============================================================================
    00535 // IAppMgrUI implementation: ApplicationMgr::initialize()
    00536 //============================================================================
    00537 StatusCode ApplicationMgr::initialize() {
    00538
    00539   MsgStream log( m_messageSvc, name() );
    00540   StatusCode sc;
    00541
    00542   if( m_state == Gaudi::StateMachine::INITIALIZED ) {
    00543     log << MSG::INFO << "Already Initialized!" << endreq;
    00544     return StatusCode::SUCCESS;
    00545   }
    00546   else if( m_state != Gaudi::StateMachine::CONFIGURED ) {
    00547     log << MSG::FATAL
    00548          << "initialize: Invalid state \""  << m_state << "\"" << endreq;
    00549     return StatusCode::FAILURE;
    00550   }
    00551   m_targetState = Gaudi::StateMachine::INITIALIZED;
    00552
    00553   //--------------------------------------------------------------------------
    00554   // Initialize the list of top Services
    00555   //--------------------------------------------------------------------------
    00556   sc = m_svcManager->initializeServices();
    00557   if( !sc.isSuccess() ) return sc;
    00558
    00559   //--------------------------------------------------------------------------
    00560   // Final steps: Inform user and change internal state
    00561   //--------------------------------------------------------------------------
    00562   log << MSG::INFO << "Application Manager Initialized successfully"  << endreq;
    00563   m_state = m_targetState;
    00564
    00565   return sc;
    00566 }
    00567
    00568 //============================================================================
    00569 // IAppMgrUI implementation: ApplicationMgr::start()
    00570 //============================================================================
    00571 StatusCode ApplicationMgr::start() {
    00572
    00573   MsgStream log( m_messageSvc, name() );
    00574   StatusCode sc;
    00575
    00576   if( m_state == Gaudi::StateMachine::RUNNING ) {
    00577     log << MSG::INFO << "Already Initialized!" << endreq;
    00578     return StatusCode::SUCCESS;
    00579   }
    00580   else if( m_state != Gaudi::StateMachine::INITIALIZED ) {
    00581     log << MSG::FATAL
    00582          << "start: Invalid state \""  << m_state << "\"" << endreq;
    00583     return StatusCode::FAILURE;
    00584   }
    00585   m_targetState = Gaudi::StateMachine::RUNNING;
    00586
    00587   //--------------------------------------------------------------------------
    00588   // Initialize the list of top Services
    00589   //--------------------------------------------------------------------------
    00590   sc = m_svcManager->startServices();
    00591   if( !sc.isSuccess() ) return sc;
    00592
    00593   //--------------------------------------------------------------------------
    00594   // Final steps: Inform user and change internal state
    00595   //--------------------------------------------------------------------------
    00596   log << MSG::INFO << "Application Manager Started successfully"  << endreq;
    00597   m_state = m_targetState;
    00598
    00599   return sc;
    00600 }
    00601
    00602 //============================================================================
    00603 // IAppMgrUI implementation: ApplicationMgr::nextEvent(int)
    00604 //============================================================================
    00605 StatusCode ApplicationMgr::nextEvent(int maxevt)    {
    00606   if( m_state != Gaudi::StateMachine::RUNNING ) {
    00607     MsgStream log( m_messageSvc, name() );
    00608     log << MSG::FATAL << "nextEvent: Invalid state \"" << m_state << "\""
    00609         << endreq;
    00610     return StatusCode::FAILURE;
    00611   }
    00612   if ( 0 == m_processingMgr )   {
    00613     MsgStream log( m_messageSvc, name() );
    00614     log << MSG::FATAL << "No event processing manager specified. Check option:"
    00615         << s_eventloop << endreq;
    00616     return StatusCode::FAILURE;
    00617   }
    00618   return m_processingMgr->nextEvent(maxevt);
    00619 }
    00620
    00621 //============================================================================
    00622 // IAppMgrUI implementation: ApplicationMgr::stop()
    00623 //============================================================================
    00624 StatusCode ApplicationMgr::stop() {
    00625
    00626   MsgStream log( m_messageSvc, name() );
    00627   StatusCode sc;
    00628
    00629   if( m_state == Gaudi::StateMachine::INITIALIZED ) {
    00630     log << MSG::INFO << "Already Initialized!" << endreq;
    00631     return StatusCode::SUCCESS;
    00632   }
    00633   else if( m_state != Gaudi::StateMachine::RUNNING ) {
    00634     log << MSG::FATAL
    00635          << "stop: Invalid state \""  << m_state << "\"" << endreq;
    00636     return StatusCode::FAILURE;
    00637   }
    00638   m_targetState = Gaudi::StateMachine::INITIALIZED;
    00639
    00640   // Stop independently managed Algorithms
    00641   sc = m_algManager->stopAlgorithms();
    00642   if( !sc.isSuccess() ) return sc;
    00643
    00644   //--------------------------------------------------------------------------
    00645   // Stop the list of top Services
    00646   //--------------------------------------------------------------------------
    00647   sc = m_svcManager->stopServices();
    00648   if( !sc.isSuccess() ) return sc;
    00649
    00650   //--------------------------------------------------------------------------
    00651   // Final steps: Inform user and change internal state
    00652   //--------------------------------------------------------------------------
    00653   log << MSG::INFO << "Application Manager Stopped successfully"  << endreq;
    00654   m_state = m_targetState;
    00655
    00656   return sc;
    00657 }
    00658
    00659 //============================================================================
    00660 // IAppMgrUI implementation: ApplicationMgr::finalize()
    00661 //============================================================================
    00662 StatusCode ApplicationMgr::finalize() {
    00663   MsgStream log( m_messageSvc, name() );
    00664   if( m_state == Gaudi::StateMachine::CONFIGURED ) {
    00665     log << MSG::INFO << "Already Finalized" << endreq;
    00666     return StatusCode::SUCCESS;
    00667   }
    00668   else if( m_state != Gaudi::StateMachine::INITIALIZED ) {
    00669     log << MSG::FATAL << "finalize: Invalid state \"" << m_state << "\""
    00670         << endreq;
    00671     return StatusCode::FAILURE;
    00672   }
    00673   m_targetState = Gaudi::StateMachine::CONFIGURED;
    00674
    00675   IProperty* msgSvcIProp = 0;
    00676   // disable message suppression in finalize
    00677   m_svcLocator->service( "MessageSvc", msgSvcIProp).ignore();
    00678   msgSvcIProp->setProperty( BooleanProperty("enableSuppression", false)).ignore();
    00679   msgSvcIProp->release();
    00680
    00681   // Finalize independently managed Algorithms
    00682   StatusCode sc = m_algManager->finalizeAlgorithms();
    00683
    00684
    00685   // Finalize all Services
    00686   sc = m_svcManager->finalizeServices();
    00687
    00688   m_svcManager->removeService( (IService*) m_processingMgr );
    00689   m_svcManager->removeService( (IService*) m_runable );
    00690
    00691   if (m_codeCheck) {
    00692     StatusCode::disableChecking();
    00693   }
    00694
    00695   log << MSG::INFO << "Application Manager Finalized successfully" << endreq;
    00696
    00697   m_state = m_targetState;
    00698   return sc;
    00699 }
    00700
    00701 //============================================================================
    00702 // IAppMgrUI implementation: ApplicationMgr::terminate()
    00703 //============================================================================
    00704 StatusCode ApplicationMgr::terminate() {
    00705   MsgStream log( m_messageSvc, name() );
    00706
    00707   if( m_state == Gaudi::StateMachine::OFFLINE ) {
    00708     log << MSG::INFO << "Already Offline" << endreq;
    00709     return StatusCode::SUCCESS;
    00710   }
    00711   else if( m_state != Gaudi::StateMachine::CONFIGURED ) {
    00712     log << MSG::FATAL << "terminate: Invalid state \"" << m_state << "\""
    00713         << endreq;
    00714     return StatusCode::FAILURE;
    00715   }
    00716   // release all Services
    00717   m_targetState = Gaudi::StateMachine::OFFLINE;
    00718
    00719
    00720   log << MSG::INFO << "Application Manager Terminated successfully" << endreq;
    00721
    00722   // finalize MessageSvc
    00723   IService *svc = 0;
    00724   StatusCode sc = m_messageSvc->queryInterface(IService::interfaceID(),pp_cast<void>(&svc));
    00725   if ( !sc.isSuccess() ) {
    00726     log << MSG::ERROR << "Could not get the IService interface of the MessageSvc" << endreq;
    00727   } else {
    00728     svc->sysFinalize().ignore();
    00729     svc->release();
    00730   }
    00731
    00732   // finalize JobOptionsSvc
    00733   svc = 0;
    00734   sc = m_jobOptionsSvc->queryInterface(IService::interfaceID(),pp_cast<void>(&svc));
    00735   if ( !sc.isSuccess() ) {
    00736     log << MSG::ERROR << "Could not get the IService interface of the JobOptionsSvc" << endreq;
    00737   } else {
    00738     svc->sysFinalize().ignore();
    00739     svc->release();
    00740   }
    00741
    00742   m_state = m_targetState;
    00743   return StatusCode::SUCCESS;
    00744 }
    00745
    00746 //============================================================================
    00747 // Reach the required state going through all the needed transitions
    00748 //============================================================================
    00749 StatusCode ApplicationMgr::GoToState(Gaudi::StateMachine::State state, bool ignoreFailures) {
    00750   StatusCode sc = StatusCode(StatusCode::SUCCESS,true);
    00751
    00752   switch (state) {
    00753
    00754   case Gaudi::StateMachine::OFFLINE:
    00755     switch (m_state) {
    00756     case Gaudi::StateMachine::OFFLINE    : return StatusCode::SUCCESS; break;
    00757     case Gaudi::StateMachine::CONFIGURED : return terminate(); break;
    00758     default: // Gaudi::StateMachine::INITIALIZED or Gaudi::StateMachine::RUNNING
    00759       sc = GoToState(Gaudi::StateMachine::CONFIGURED);
    00760       if (sc.isSuccess()) {
    00761         return terminate();
    00762       } break;
    00763     } break;
    00764
    00765   case Gaudi::StateMachine::CONFIGURED:
    00766     switch (m_state) {
    00767     case Gaudi::StateMachine::CONFIGURED  : return StatusCode::SUCCESS; break;
    00768     case Gaudi::StateMachine::OFFLINE     : return configure(); break;
    00769     case Gaudi::StateMachine::INITIALIZED : return finalize(); break;
    00770     default: // Gaudi::StateMachine::RUNNING
    00771       sc = GoToState(Gaudi::StateMachine::INITIALIZED);
    00772       if (sc.isSuccess()) {
    00773         return finalize();
    00774       } break;
    00775     } break;
    00776
    00777   case Gaudi::StateMachine::INITIALIZED:
    00778     switch (m_state) {
    00779     case Gaudi::StateMachine::INITIALIZED : return StatusCode::SUCCESS; break;
    00780     case Gaudi::StateMachine::CONFIGURED  : return initialize(); break;
    00781     case Gaudi::StateMachine::RUNNING     : return stop(); break;
    00782     default: // Gaudi::StateMachine::OFFLINE
    00783       sc = GoToState(Gaudi::StateMachine::CONFIGURED);
    00784       if (sc.isSuccess()) {
    00785         return initialize();
    00786       } break;
    00787     } break;
    00788
    00789   case Gaudi::StateMachine::RUNNING:
    00790     switch (m_state) {
    00791     case Gaudi::StateMachine::RUNNING     : return StatusCode::SUCCESS; break;
    00792     case Gaudi::StateMachine::INITIALIZED : return start(); break;
    00793     default: // Gaudi::StateMachine::OFFLINE or Gaudi::StateMachine::CONFIGURED
    00794       sc = GoToState(Gaudi::StateMachine::INITIALIZED);
    00795       if (sc.isSuccess()) {
    00796         return start();
    00797       } break;
    00798     } break;
    00799
    00800   }
    00801
    00802   // If I get here, there has been a problem in the recursion
    00803
    00804   if (ignoreFailures){
    00805     // force the new state
    00806     m_state = state;
    00807     return StatusCode::SUCCESS;
    00808   }
    00809
    00810   return sc;
    00811 }
    00812
    00813 //============================================================================
    00814 // IAppMgrUI implementation: ApplicationMgr::run()
    00815 //============================================================================
    00816 StatusCode ApplicationMgr::run() {
    00817   StatusCode sc = StatusCode::SUCCESS;
    00818
    00819   sc = GoToState(Gaudi::StateMachine::RUNNING);
    00820   if ( sc.isSuccess() ) {
    00821     MsgStream log(m_messageSvc, name());
    00822     if ( 0 != m_runable ) { // loop over the events
    00823       sc = m_runable->run();
    00824       if ( !sc.isSuccess() ) {
    00825         log << MSG::FATAL << "Application execution failed. Ending the job."
    00826             << endreq;
    00827       }
    00828     } else {
    00829       log << MSG::FATAL << "Application has no runable object. Check option:"
    00830           << s_runable << endreq;
    00831     }
    00832   }
    00833   if (sc.isSuccess()) { // try to close cleanly
    00834     sc = GoToState(Gaudi::StateMachine::OFFLINE);
    00835   }
    00836   // either the runable failed of the stut-down
    00837   if (sc.isFailure()) { // try to close anyway (but keep the StatusCode unchanged)
    00838     GoToState(Gaudi::StateMachine::OFFLINE,true).ignore();
    00839   }
    00840   return sc;
    00841 }
    00842
    00843 //============================================================================
    00844 // IEventProcessor implementation: executeEvent(void* par)
    00845 //============================================================================
    00846 StatusCode ApplicationMgr::executeEvent(void* par)    {
    00847   MsgStream log( m_messageSvc, name() );
    00848   if( m_state == Gaudi::StateMachine::RUNNING ) {
    00849     SmartIF<IEventProcessor> processor(IID_IEventProcessor, m_processingMgr);
    00850     if ( processor.isValid() )    {
    00851       return processor->executeEvent(par);
    00852     }
    00853   }
    00854   log << MSG::FATAL << "executeEvent: Invalid state \"" << FSMState() << "\""
    00855       <<endreq;
    00856   return StatusCode::FAILURE;
    00857 }
    00858
    00859 //============================================================================
    00860 // IEventProcessor implementation: executeRun(int)
    00861 //============================================================================
    00862 StatusCode ApplicationMgr::executeRun(int evtmax)    {
    00863   MsgStream log( m_messageSvc, name() );
    00864   if( m_state == Gaudi::StateMachine::RUNNING ) {
    00865     SmartIF<IEventProcessor> processor(IID_IEventProcessor, m_processingMgr);
    00866     if ( processor.isValid() )    {
    00867       return processor->executeRun(evtmax);
    00868     }
    00869     log << MSG::WARNING << "No EventLoop Manager specified " << endreq;
    00870     return StatusCode::SUCCESS;
    00871   }
    00872   log << MSG::FATAL << "executeRun: Invalid state \"" << FSMState() << "\""
    00873       << endreq;
    00874   return StatusCode::FAILURE;
    00875 }
    00876
    00877 //============================================================================
    00878 // IEventProcessor implementation: stopRun(int)
    00879 //============================================================================
    00880 StatusCode ApplicationMgr::stopRun()    {
    00881   MsgStream log( m_messageSvc, name() );
    00882   if( m_state == Gaudi::StateMachine::RUNNING ) {
    00883     SmartIF<IEventProcessor> processor(IID_IEventProcessor, m_processingMgr);
    00884     if ( processor.isValid() )    {
    00885       return processor->stopRun();
    00886     }
    00887     log << MSG::WARNING << "No EventLoop Manager specified " << endreq;
    00888     return StatusCode::SUCCESS;
    00889   }
    00890   log << MSG::FATAL << "stopRun: Invalid state \"" << FSMState() << "\""
    00891       << endreq;
    00892   return StatusCode::FAILURE;
    00893 }
    00894 // Implementation of IAppMgrUI::name
    00895 const std::string& ApplicationMgr::name() const {
    00896   return m_name;
    00897 }
    00898
    00899 // implementation of IService::type
    00900 const InterfaceID& ApplicationMgr::type() const {
    00901   return IID_IService;
    00902 }
    00903 // implementation of IService::state
    00904 Gaudi::StateMachine::State ApplicationMgr::FSMState( ) const {
    00905   return m_state;
    00906 }
    00907 // implementation of IService::state
    00908 Gaudi::StateMachine::State ApplicationMgr::targetFSMState( ) const {
    00909   return m_targetState;
    00910 }
    00911
    00912
    00913 //============================================================================
    00914 // implementation of IService::reinitilaize
    00915 //============================================================================
    00916 StatusCode ApplicationMgr::reinitialize() {
    00917   StatusCode retval = StatusCode::SUCCESS;
    00918   StatusCode sc;
    00919   if ( m_state < Gaudi::StateMachine::INITIALIZED ) {
    00920     throw GaudiException("Cannot reinitialize application if not INITIALIZED or RUNNING",
    00921                          "ApplicationMgr::reinitialize", StatusCode::FAILURE);
    00922   }
    00923   if ( m_state == Gaudi::StateMachine::RUNNING ) {
    00924     retval = GoToState(Gaudi::StateMachine::INITIALIZED);
    00925   }
    00926   sc = m_svcManager->reinitializeServices();
    00927   if (sc.isFailure()) retval = sc;
    00928   sc = m_algManager->reinitializeAlgorithms();
    00929   if (sc.isFailure()) retval = sc;
    00930   return retval;
    00931 }
    00932
    00933 //============================================================================
    00934 // implementation of IService::reinitilaize
    00935 //============================================================================
    00936 StatusCode ApplicationMgr::restart() {
    00937   StatusCode retval = StatusCode::SUCCESS;
    00938   StatusCode sc;
    00939   if ( m_state != Gaudi::StateMachine::RUNNING ) {
    00940     throw GaudiException("Cannot restart application if not RUNNING",
    00941                          "ApplicationMgr::restart", StatusCode::FAILURE);
    00942   }
    00943   sc = m_svcManager->restartServices();
    00944   if (sc.isFailure()) retval = sc;
    00945   sc = m_algManager->restartAlgorithms();
    00946   if (sc.isFailure()) retval = sc;
    00947   return retval;
    00948 }
    00949
    00950 //============================================================================
    00951 // SI Go Handler
    00952 //============================================================================
    00953 void ApplicationMgr::SIGoHandler( Property& ) {
    00954
    00955   MsgStream log (m_messageSvc, name());
    00956   StatusCode sc;
    00957
    00958   // Re-initialize everything
    00959   sc = reinitialize();
    00960   // Execute a number of events
    00961   executeRun(m_evtMax);
    00962
    00963   return;
    00964 }
    00965
    00966 //============================================================================
    00967 // SI Exit Handler
    00968 //============================================================================
    00969 void ApplicationMgr::SIExitHandler( Property& ) {
    00970   StatusCode status;
    00971   status = finalize();
    00972   status = terminate();
    00973   ::exit( 0 );
    00974 }
    00975
    00976 //============================================================================
    00977 // Handle properties of the event loop manager (Top alg/Output stream list)
    00978 //============================================================================
    00979 void ApplicationMgr::evtLoopPropertyHandler( Property& p ) {
    00980   if ( m_processingMgr )    {
    00981     SmartIF<IProperty> props(IID_IProperty, m_processingMgr);
    00982     if ( props.isValid() )    {
    00983       props->setProperty( p ).ignore();
    00984     }
    00985   }
    00986 }
    00987
    00988 //============================================================================
    00989 // External Service List handler
    00990 //============================================================================
    00991 void ApplicationMgr::createSvcNameListHandler( Property& /* theProp */ ) {
    00992   if ( !(decodeCreateSvcNameList()).isSuccess() ) {
    00993     throw GaudiException("Failed to create ext services",
    00994                          "MinimalEventLoopMgr::createSvcNameListHandler",
    00995                          StatusCode::FAILURE);
    00996   }
    00997 }
    00998 //============================================================================
    00999 //  decodeCreateSvcNameList
    01000 //============================================================================
    01001 StatusCode ApplicationMgr::decodeCreateSvcNameList() {
    01002   StatusCode result = StatusCode::SUCCESS;
    01003   const std::vector<std::string>& theNames = m_createSvcNameList.value( );
    01004   VectorName::const_iterator it(theNames.begin());
    01005   VectorName::const_iterator et(theNames.end());
    01006   while(result.isSuccess() && it != et) {
    01007     ListItem item(*it++);
    01008     if( (result = m_svcManager->addService(item.type(), item.name(), 10) ).isFailure()) {
    01009       MsgStream log( m_messageSvc, m_name );
    01010       log << MSG::ERROR << "decodeCreateSvcNameList: Cannot create service "
    01011           << item.type() << "/" << item.name() << endmsg;
    01012     } else {
    01013       MsgStream log( m_messageSvc, m_name );
    01014       log << MSG::DEBUG << "decodeCreateSvcNameList: Created service "
    01015           << item.type() << "/" << item.name() << endmsg;
    01016     }
    01017   }
    01018   return result;
    01019 }
    01020
    01021 //============================================================================
    01022 // External Service List handler
    01023 //============================================================================
    01024 void ApplicationMgr::extSvcNameListHandler( Property& /* theProp */ ) {
    01025   if ( !(decodeExtSvcNameList( )).isSuccess() ) {
    01026     throw GaudiException("Failed to declare ext services",
    01027                          "MinimalEventLoopMgr::extSvcNameListHandler",
    01028                          StatusCode::FAILURE);
    01029   }
    01030 }
    01031
    01032 //============================================================================
    01033 //  decodeExtSvcNameList
    01034 //============================================================================
    01035 StatusCode ApplicationMgr::decodeExtSvcNameList( ) {
    01036   StatusCode result = StatusCode::SUCCESS;
    01037
    01038   std::vector<std::string> theNames = m_extSvcNameList.value( );
    01039
    01040   VectorName::const_iterator it(theNames.begin());
    01041   VectorName::const_iterator et(theNames.end());
    01042   while(result.isSuccess() && it != et) {
    01043     ListItem item(*it++);
    01044     if (m_extSvcCreates == true) {
    01045       if ( (result = m_svcManager->addService(item.type(),
    01046                                               item.name(), 10)).isFailure()) {
    01047         MsgStream log( m_messageSvc, m_name );
    01048         log << MSG::ERROR << "decodeExtSvcNameList: Cannot create service "
    01049             << item.type() << "/" << item.name() << endmsg;
    01050       }
    01051     } else {
    01052       if( ( result = m_svcManager->declareSvcType(item.name(),
    01053                                                   item.type()) ).isFailure()) {
    01054         MsgStream log( m_messageSvc, m_name );
    01055         log << MSG::ERROR << "decodeExtSvcNameList: Cannot declare service "
    01056             << item.type() << "/" << item.name() << endmsg;
    01057       }
    01058     }
    01059   }
    01060   return result;
    01061 }
    01062
    01063 //============================================================================
    01064 // External Service List handler
    01065 //============================================================================
    01066 void ApplicationMgr::multiThreadSvcNameListHandler( Property& /* theProp */ ) {
    01067   if ( !(decodeMultiThreadSvcNameList( )).isSuccess() ) {
    01068     throw GaudiException("Failed to create copies of mt services",
    01069                          "MinimalEventLoopMgr::multiThreadSvcNameListHandler",
    01070                          StatusCode::FAILURE);
    01071   }
    01072
    01073 }
    01074
    01075 //============================================================================
    01076 //  decodeMultiExtSvcNameList
    01077 //============================================================================
    01078 StatusCode ApplicationMgr::decodeMultiThreadSvcNameList( ) {
    01079   StatusCode result = StatusCode::SUCCESS;
    01080   const std::vector<std::string>& theNames = m_multiThreadSvcNameList.value( );
    01081   for(int iCopy=0; iCopy<m_noOfEvtThreads; ++iCopy) {
    01082     for (VectorName::const_iterator it = theNames.begin();
    01083          it != theNames.end();
    01084          ++it) {
    01085       ListItem item(*it);
    01086       result = addMultiSvc(item.type(), item.name(), 10);
    01087       //FIXME SHOULD CLONE?
    01088       if( result.isFailure() ) {
    01089         MsgStream log( m_messageSvc, m_name );
    01090         log << MSG::ERROR
    01091             << "decodeMultiThreadSvcNameList: Cannot create service "
    01092             << item.type() << "/" << item.name() << endmsg;
    01093       } else {
    01094         MsgStream log( m_messageSvc, m_name );
    01095         log << MSG::VERBOSE
    01096             << "decodeMultiThreadSvcNameList: created service "
    01097             << item.type() << "/" << item.name() << endmsg;
    01098       }
    01099     }
    01100   }
    01101   return result;
    01102 }
    01103 //=============================================================================
    01104 //  declareMultiSvcType
    01105 //=============================================================================
    01106 StatusCode ApplicationMgr::declareMultiSvcType(const std::string& name,
    01107                                                const std::string& type) {
    01108   StatusCode result = StatusCode::SUCCESS;
    01109   MsgStream log( m_messageSvc, m_name );
    01110   if (0 == m_noOfEvtThreads) {
    01111     result = m_svcManager->declareSvcType(name, type);
    01112     if( result.isFailure() ) {
    01113       log << MSG::ERROR << "declareMultiSvcType: Cannot declare service "
    01114           << type << "/" << name << endmsg;
    01115     } else {
    01116       log << MSG::VERBOSE << "declareMultiSvcType: declared service "
    01117           << type << "/" << name << endmsg;
    01118     }
    01119   } else {
    01120     for(int iCopy=0; iCopy<m_noOfEvtThreads; ++iCopy) {
    01121       std::string thrName(name + getGaudiThreadIDfromID(iCopy));
    01122       result = m_svcManager->declareSvcType(thrName, type);
    01123       if( result.isFailure() ) {
    01124         log << MSG::ERROR << "declareMultiSvcType: Cannot declare service "
    01125             << type << "/" << thrName << endmsg;
    01126       } else {
    01127         log << MSG::VERBOSE << "declareMultiSvcType: declared service "
    01128             << type << "/" << thrName << endmsg;
    01129       }
    01130     }
    01131   }
    01132   return result;
    01133 }
    01134 //=============================================================================
    01135 //  addMultiSvc
    01136 //=============================================================================
    01137 StatusCode ApplicationMgr::addMultiSvc(const std::string& type,
    01138                                        const std::string& name,
    01139                                        int prio) {
    01140   StatusCode result = StatusCode::SUCCESS;
    01141   MsgStream log( m_messageSvc, m_name );
    01142   if (0 == m_noOfEvtThreads) {
    01143     result = m_svcManager->addService(type, name, prio);
    01144     // result = m_svcManager->addService(name, type, prio); // CHECKME???
    01145     if( result.isFailure() ) {
    01146       log << MSG::ERROR << "addMultiSvc: Cannot add service "
    01147           << type << "/" << name << endmsg;
    01148     } else {
    01149       log << MSG::VERBOSE << "addMultiSvc: added service "
    01150           << type << "/" << name << endmsg;
    01151     }
    01152   } else {
    01153     for(int iCopy=0; iCopy<m_noOfEvtThreads; ++iCopy) {
    01154       std::string thrName(name + getGaudiThreadIDfromID(iCopy));
    01155       result = m_svcManager->addService(type, thrName, prio);
    01156       if( result.isFailure() ) {
    01157         log << MSG::ERROR << "addMultiSvc: Cannot add service "
    01158             << type << "/" << thrName << endmsg;
    01159       } else {
    01160         log << MSG::VERBOSE << "addMultiSvc: added service "
    01161             << type << "/" << thrName << endmsg;
    01162       }
    01163     }
    01164   }
    01165   return result;
    01166 }
    01167
    01168 //============================================================================
    01169 // Dll List handler
    01170 //============================================================================
    01171 void ApplicationMgr::dllNameListHandler( Property& /* theProp */ ) {
    01172   if ( !(decodeDllNameList( )).isSuccess() ) {
    01173     throw GaudiException("Failed to load DLLs.",
    01174                          "MinimalEventLoopMgr::dllNameListHandler",
    01175                          StatusCode::FAILURE);
    01176   }
    01177 }
    01178
    01179 //============================================================================
    01180 //  decodeDllNameList
    01181 //============================================================================
    01182 StatusCode ApplicationMgr::decodeDllNameList() {
    01183
    01184   MsgStream log( m_messageSvc, m_name );
    01185   StatusCode result = StatusCode::SUCCESS;
    01186
    01187   // Clean up multiple entries from DLL list
    01188   // -------------------------------------------------------------------------
    01189   std::vector<std::string> newList;
    01190   std::map<std::string,unsigned int> dllInList, duplicateList;
    01191   {for ( std::vector<std::string>::const_iterator it = m_dllNameList.value().begin();
    01192         it != m_dllNameList.value().end(); ++it ) {
    01193     if ( 0 == dllInList[*it] ) {
    01194       newList.push_back(*it);        // first instance of this module
    01195     } else { ++duplicateList[*it]; } // module listed multiple times
    01196     ++dllInList[*it];                // increment count for this module
    01197   }}
    01198   //m_dllNameList = newList; // update primary list to new, filtered list (do not use the
    01199                              // property itself otherwise we get called again infinitely)
    01200   // List modules that were in there twice..
    01201   if ( !duplicateList.empty() ) {
    01202     log << MSG::DEBUG << "Removed duplicate entries for modules : ";
    01203     for ( std::map<std::string,unsigned int>::const_iterator it = duplicateList.begin();
    01204           it != duplicateList.end(); ++it ) {
    01205       log << it->first << "(" << 1+it->second << ")";
    01206       if ( it != --duplicateList.end() ) log << ", ";
    01207     }
    01208     log << endreq;
    01209   }
    01210   // -------------------------------------------------------------------------
    01211
    01212   const std::vector<std::string>& theNames = newList;
    01213
    01214   // only load the new dlls or previously failed dlls
    01215   log << MSG::DEBUG << "Loading declared DLL's" << endreq;
    01216
    01217   std::vector<std::string> successNames, failNames;
    01218   std::vector<std::string>::const_iterator it;
    01219
    01220   for (it = theNames.begin(); it != theNames.end(); it++) {
    01221     if (std::find (m_okDlls.rbegin(), m_okDlls.rend(), *it) == m_okDlls.rend()){
    01222       // found a new module name
    01223       StatusCode status = m_classManager->loadModule( (*it) );
    01224       if( status.isFailure() ) {
    01225         failNames.push_back(*it);
    01226         result = StatusCode::FAILURE;
    01227       }
    01228       else {
    01229         successNames.push_back(*it);
    01230       }
    01231     }
    01232   }
    01233
    01234   // report back to the user and store the names of the succesfully loaded dlls
    01235   if ( !successNames.empty() ) {
    01236     log << MSG::INFO << "Successfully loaded modules : ";
    01237     for (it = successNames.begin(); it != successNames.end(); it++) {
    01238       log<< (*it);
    01239       if( (it+1) != successNames.end())  log << ", ";
    01240       // save name
    01241       m_okDlls.push_back( *it );
    01242     }
    01243     log << endmsg;
    01244   }
    01245
    01246   if ( result == StatusCode::FAILURE ) {
    01247     log << MSG::WARNING << "Failed to load modules: ";
    01248     for (it = failNames.begin(); it != failNames.end(); it++) {
    01249       log<< (*it);
    01250       if( (it+1) != failNames.end())  log << ", ";
    01251     }
    01252     log << endmsg;
    01253   }
    01254   return result;
    01255 }
    01256
    01257 //============================================================================
    01258 // Reflex debug level handler
    01259 //============================================================================
    01260 void ApplicationMgr::reflexDebugPropertyHandler( Property& )
    01261 {
    01262   // Setup debug level for Reflex plugin system
    01263   MsgStream log (m_messageSvc, name());
    01264   log << MSG::INFO
    01265       << "Updating ROOT::Reflex::PluginService::SetDebug(level) to level="
    01266       << (int)m_reflexDebugLevel
    01267       << endreq;
    01268   ROOT::Reflex::PluginService::SetDebug(m_reflexDebugLevel);
    01269 }
    01270
    01271 //============================================================================
    01272 // Reflex debug level handler
    01273 //============================================================================
    01274 void ApplicationMgr::initLoopCheckHndlr(Property&) {
    01275   m_svcManager->setLoopCheckEnabled(m_loopCheck);
    01276 }