The Gaudi Framework  v30r3 (a5ef0a68)
AlgorithmManager.cpp
Go to the documentation of this file.
1 // Include files
2 #include "AlgorithmManager.h"
8 #include "GaudiKernel/System.h"
10 #include <iostream>
11 #ifndef _WIN32
12 #include <errno.h>
13 #endif
14 
16 static SmartIF<IAlgorithm> no_algorithm;
17 
18 // constructor
19 AlgorithmManager::AlgorithmManager( IInterface* application ) : base_class( application, IAlgorithm::interfaceID() )
20 {
21  addRef(); // Initial count set to 1
22 }
23 
24 // addAlgorithm
26 {
27  m_algs.push_back( alg );
28  return StatusCode::SUCCESS;
29 }
30 
31 // removeAlgorithm
33 {
34  auto it = std::find( m_algs.begin(), m_algs.end(), alg );
35  if ( it != m_algs.end() ) {
36  m_algs.erase( it );
37  return StatusCode::SUCCESS;
38  }
39  return StatusCode::FAILURE;
40 }
41 
42 // createService
44  IAlgorithm*& algorithm, bool managed, bool checkIfExists )
45 {
46  // Check is the algorithm is already existing
47  if ( checkIfExists ) {
48  if ( existsAlgorithm( algname ) ) {
49  // return an error because an algorithm with that name already exists
50  return StatusCode::FAILURE;
51  }
52  }
53  std::string actualalgtype( algtype );
54  // a '\' in front of the type name prevents alias replacement
55  if ( ( actualalgtype.size() > 8 ) && ( actualalgtype.compare( 0, 8, "unalias:" ) == 0 ) ) {
56  actualalgtype = actualalgtype.substr( 8 );
57  } else {
58  auto typeAlias = m_algTypeAliases.find( algtype );
59  if ( typeAlias != m_algTypeAliases.end() ) {
60  actualalgtype = typeAlias->second;
61  }
62  }
63  algorithm = Algorithm::Factory::create( actualalgtype, algname, serviceLocator().get() ).release();
64  if ( !algorithm ) {
65  this->error() << "Algorithm of type " << actualalgtype << " is unknown (No factory available)." << endmsg;
66 #ifndef _WIN32
67  errno =
68  0xAFFEDEAD; // code used by Gaudi for library load errors: forces getLastErrorString do use dlerror (on Linux)
69 #endif
71  if ( !err.empty() ) this->error() << err << endmsg;
72  this->error() << "More information may be available by setting the global jobOpt \"PluginDebugLevel\" to 1"
73  << endmsg;
74  return StatusCode::FAILURE;
75  }
76  // Check the compatibility of the version of the interface obtained
77  if ( !isValidInterface( algorithm ) ) {
78  fatal() << "Incompatible interface IAlgorithm version for " << actualalgtype << endmsg;
79  return StatusCode::FAILURE;
80  }
81  m_algs.emplace_back( algorithm, managed );
82  // let the algorithm know its type
83  algorithm->setType( algtype );
84  // this is needed to keep the reference count correct, since isValidInterface(algorithm)
85  // implies an increment of the counter by 1
86  algorithm->release();
87  StatusCode rc;
88  if ( managed ) {
89  // Bring the created algorithm to the same state of the ApplicationMgr
91  rc = algorithm->sysInitialize();
92  if ( rc.isSuccess() && FSMState() >= Gaudi::StateMachine::RUNNING ) {
93  rc = algorithm->sysStart();
94  }
95  }
96  if ( !rc.isSuccess() ) {
97  this->error() << "Failed to initialize algorithm: [" << algname << "]" << endmsg;
98  }
99  }
100  return rc;
101 }
102 
104 {
105  auto it = std::find( m_algs.begin(), m_algs.end(), typeName.name() );
106  if ( it != m_algs.end() ) { // found
107  return it->algorithm;
108  }
109  if ( createIf ) {
110  IAlgorithm* alg;
111  if ( createAlgorithm( typeName.type(), typeName.name(), alg, true ).isSuccess() ) {
112  return algorithm( typeName, false );
113  }
114  }
115  return no_algorithm;
116 }
117 
118 // existsAlgorithm
120 {
121  return m_algs.end() != std::find( m_algs.begin(), m_algs.end(), name );
122 }
123 
124 // Return the list of Algorithms
126 {
128  m_listOfPtrs.reserve( m_algs.size() );
130  []( const AlgorithmItem& alg ) { return const_cast<IAlgorithm*>( alg.algorithm.get() ); } );
131  return m_listOfPtrs;
132 }
133 
135 {
136  StatusCode rc;
137  for ( auto& it : m_algs ) {
138  if ( !it.managed ) continue;
139  rc = it.algorithm->sysInitialize();
140  if ( rc.isFailure() ) return rc;
141  }
142  return rc;
143 }
144 
146 {
147  StatusCode rc;
148  for ( auto& it : m_algs ) {
149  if ( !it.managed ) continue;
150  rc = it.algorithm->sysStart();
151  if ( rc.isFailure() ) return rc;
152  }
153  return rc;
154 }
155 
157 {
158  StatusCode rc;
159  for ( auto& it : m_algs ) {
160  if ( !it.managed ) continue;
161  rc = it.algorithm->sysStop();
162  if ( rc.isFailure() ) return rc;
163  }
164  return rc;
165 }
166 
168 {
169  StatusCode rc;
170  auto it = m_algs.begin();
171  while ( it != m_algs.end() ) { // finalize and remove from the list the managed algorithms
172  if ( it->managed ) {
173  rc = it->algorithm->sysFinalize();
174  if ( rc.isFailure() ) return rc;
175  it = m_algs.erase( it );
176  } else {
177  ++it;
178  }
179  }
180  return rc;
181 }
182 
184 {
185  StatusCode rc;
186  for ( auto& it : m_algs ) {
187  if ( !it.managed ) continue;
188  rc = it.algorithm->sysReinitialize();
189  if ( rc.isFailure() ) {
190  this->error() << "Unable to re-initialize algorithm: " << it.algorithm->name() << endmsg;
191  return rc;
192  }
193  }
194  return rc;
195 }
196 
198 {
200  m_aess = serviceLocator()->service( "AlgExecStateSvc" );
201  if ( !m_aess.isValid() ) {
202  fatal() << "Error retrieving AlgExecStateSvc" << endmsg;
203  return StatusCode::FAILURE;
204  }
205 
206  StatusCode rc;
207 
208  for ( auto& it : m_algs ) {
209  if ( !it.managed ) continue;
210  rc = it.algorithm->sysRestart();
211  m_aess->resetErrorCount( it.algorithm );
212  if ( rc.isFailure() ) {
213  this->error() << "Unable to re-initialize algorithm: " << it.algorithm->name() << endmsg;
214  return rc;
215  }
216  }
217  return rc;
218 }
219 
221 {
222  resetMessaging();
223  for ( auto& algItem : m_algs ) {
224  const auto alg = dynamic_cast<Algorithm*>( algItem.algorithm.get() );
225  if ( alg ) alg->resetMessaging();
226  }
227 }
void outputLevelUpdate() override
Function to call to update the outputLevel of the components (after a change in MessageSvc).
StatusCode initialize() override
Initialization (from CONFIGURED to INITIALIZED).
constexpr static const auto FAILURE
Definition: StatusCode.h:88
T empty(T...args)
StatusCode addAlgorithm(IAlgorithm *alg) override
implementation of IAlgManager::addAlgorithm
StatusCode start() override
Start (from INITIALIZED to RUNNING).
const std::string & name() const override
Return the name of the manager (implementation of INamedInterface)
const std::vector< IAlgorithm * > & getAlgorithms() const override
implementation of IAlgManager::getAlgorithms
virtual StatusCode sysStart()=0
Startup method invoked by the framework.
AlgTypeAliasesMap m_algTypeAliases
std::vector< AlgorithmItem > m_algs
algorithms maintained by AlgorithmManager
MSG::Level resetMessaging()
Reinitialize internal states.
bool isSuccess() const
Definition: StatusCode.h:287
std::vector< IAlgorithm * > m_listOfPtrs
List of pointers to the know services used to implement getAlgorithms()
Gaudi::StateMachine::State FSMState() const override
Get the current state.
T end(T...args)
StatusCode reinitialize() override
Initialization (from INITIALIZED or RUNNING to INITIALIZED, via CONFIGURED).
bool isValidInterface(I *i)
Templated function that throws an exception if the version if the interface implemented by the object...
Definition: IInterface.h:378
bool isFailure() const
Definition: StatusCode.h:139
SmartIF< ISvcLocator > & serviceLocator() const override
StatusCode stop() override
Stop (from RUNNING to INITIALIZED).
MsgStream & err() const
shortcut for the method msgStream(MSG::ERROR)
StatusCode finalize() override
Finalize (from INITIALIZED to CONFIGURED).
virtual StatusCode sysInitialize()=0
Initialization method invoked by the framework.
STL class.
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:82
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:79
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
Helper class to parse a string of format "type/name".
bool existsAlgorithm(const std::string &name) const override
implementation of IAlgManager::existsAlgorithm
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:51
Definition of the basic interface.
Definition: IInterface.h:277
StatusCode removeAlgorithm(IAlgorithm *alg) override
implementation of IAlgManager::removeAlgorithm
T clear(T...args)
The IAlgorithm is the interface implemented by the Algorithm base class.
Definition: IAlgorithm.h:28
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
virtual void setType(const std::string &)=0
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:78
T find(T...args)
T size(T...args)
bool isValid() const
Allow for check if smart pointer is valid.
Definition: SmartIF.h:68
T begin(T...args)
T back_inserter(T...args)
const std::string & type() const
T substr(T...args)
AlgorithmManager(IInterface *iface)
default creator
SmartIF< IAlgorithm > & algorithm(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true) override
T transform(T...args)
GAUDI_API const std::string getLastErrorString()
Get last system error as string.
Definition: System.cpp:294
const std::string & name() const
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
std::string typeName(const std::type_info &typ)
Definition: Dictionary.cpp:23
virtual void resetErrorCount(const IAlgorithm *iAlg)=0
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
T compare(T...args)
StatusCode createAlgorithm(const std::string &algtype, const std::string &algname, IAlgorithm *&algorithm, bool managed=false, bool checkIfExists=true) override
implementation of IAlgManager::createAlgorithm
SmartIF< IAlgorithm > algorithm
T reserve(T...args)
StatusCode restart() override
Initialization (from RUNNING to RUNNING, via INITIALIZED).