| # Gaudi Framework, version v20r2
Generated: 18 Jul 2008

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

- Search for |

- File List
- File Members

# ApplicationMgr.cpp

Go to the documentation of this file.

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