The Gaudi Framework  v33r0 (d5ea422b)
AlgorithmManager.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 // Include files
12 #include "AlgorithmManager.h"
14 #include "GaudiKernel/IAlgorithm.h"
16 #include "GaudiKernel/MsgStream.h"
17 #include "GaudiKernel/System.h"
19 #include <Gaudi/Algorithm.h>
20 #include <iostream>
21 #ifndef _WIN32
22 # include <errno.h>
23 #endif
24 
26 static SmartIF<IAlgorithm> no_algorithm;
27 
28 // constructor
30  addRef(); // Initial count set to 1
31 }
32 
33 // addAlgorithm
35  m_algs.push_back( alg );
36  return StatusCode::SUCCESS;
37 }
38 
39 // removeAlgorithm
41  auto it = std::find( m_algs.begin(), m_algs.end(), alg );
42  if ( it != m_algs.end() ) {
43  m_algs.erase( it );
44  return StatusCode::SUCCESS;
45  }
46  return StatusCode::FAILURE;
47 }
48 
49 // createService
51  IAlgorithm*& algorithm, bool managed, bool checkIfExists ) {
52  // Check is the algorithm is already existing
53  if ( checkIfExists ) {
54  if ( existsAlgorithm( algname ) ) {
55  // return an error because an algorithm with that name already exists
56  return StatusCode::FAILURE;
57  }
58  }
59  std::string actualalgtype( algtype );
60  // a '\' in front of the type name prevents alias replacement
61  if ( ( actualalgtype.size() > 8 ) && ( actualalgtype.compare( 0, 8, "unalias:" ) == 0 ) ) {
62  actualalgtype = actualalgtype.substr( 8 );
63  } else {
64  auto typeAlias = m_algTypeAliases.find( algtype );
65  if ( typeAlias != m_algTypeAliases.end() ) { actualalgtype = typeAlias->second; }
66  }
67  algorithm = Gaudi::Algorithm::Factory::create( actualalgtype, algname, serviceLocator().get() ).release();
68  if ( !algorithm ) {
69  this->error() << "Algorithm of type " << actualalgtype << " is unknown (No factory available)." << endmsg;
70 #ifndef _WIN32
71  errno =
72  0xAFFEDEAD; // code used by Gaudi for library load errors: forces getLastErrorString do use dlerror (on Linux)
73 #endif
75  if ( !err.empty() ) this->error() << err << endmsg;
76  this->error() << "More information may be available by setting the global jobOpt \"PluginDebugLevel\" to 1"
77  << endmsg;
78  return StatusCode::FAILURE;
79  }
80  // Check the compatibility of the version of the interface obtained
81  if ( !isValidInterface( algorithm ) ) {
82  fatal() << "Incompatible interface IAlgorithm version for " << actualalgtype << endmsg;
83  return StatusCode::FAILURE;
84  }
85  m_algs.emplace_back( algorithm, managed );
86  // let the algorithm know its type
87  algorithm->setType( algtype );
88  // this is needed to keep the reference count correct, since isValidInterface(algorithm)
89  // implies an increment of the counter by 1
90  algorithm->release();
91  StatusCode rc;
92  if ( managed ) {
93  // Bring the created algorithm to the target state of the ApplicationMgr
96  if ( rc.isSuccess() && targetFSMState() >= Gaudi::StateMachine::RUNNING ) { rc = algorithm->sysStart(); }
97  }
98  if ( !rc.isSuccess() ) { this->error() << "Failed to initialize algorithm: [" << algname << "]" << endmsg; }
99  }
100  return rc;
101 }
102 
104  auto it = std::find( m_algs.begin(), m_algs.end(), typeName.name() );
105  if ( it != m_algs.end() ) { // found
106  return it->algorithm;
107  }
108  if ( createIf ) {
109  IAlgorithm* alg;
110  if ( createAlgorithm( typeName.type(), typeName.name(), alg, true ).isSuccess() ) {
111  return algorithm( typeName, false );
112  }
113  }
114  return no_algorithm;
115 }
116 
117 // existsAlgorithm
119  return m_algs.end() != std::find( m_algs.begin(), m_algs.end(), name );
120 }
121 
122 // Return the list of Algorithms
125  m_listOfPtrs.reserve( m_algs.size() );
127  []( const AlgorithmItem& alg ) { return alg.algorithm.get(); } );
128  return m_listOfPtrs;
129 }
130 
132  StatusCode rc;
133  for ( auto& it : m_algs ) {
134  if ( !it.managed || it.algorithm->FSMState() >= Gaudi::StateMachine::INITIALIZED ) continue;
135  rc = it.algorithm->sysInitialize();
136  if ( rc.isFailure() ) return rc;
137  }
138  return rc;
139 }
140 
142  StatusCode rc;
143  for ( auto& it : m_algs ) {
144  if ( !it.managed || it.algorithm->FSMState() >= Gaudi::StateMachine::RUNNING ) continue;
145  rc = it.algorithm->sysStart();
146  if ( rc.isFailure() ) return rc;
147  }
148  return rc;
149 }
150 
152  StatusCode rc;
153  for ( auto& it : m_algs ) {
154  if ( !it.managed ) continue;
155  rc = it.algorithm->sysStop();
156  if ( rc.isFailure() ) return rc;
157  }
158  return rc;
159 }
160 
162  StatusCode rc;
163  auto it = m_algs.begin();
164  while ( it != m_algs.end() ) { // finalize and remove from the list the managed algorithms
165  if ( it->managed ) {
166  rc = it->algorithm->sysFinalize();
167  if ( rc.isFailure() ) return rc;
168  it = m_algs.erase( it );
169  } else {
170  ++it;
171  }
172  }
173  return rc;
174 }
175 
177  StatusCode rc;
178  for ( auto& it : m_algs ) {
179  if ( !it.managed ) continue;
180  rc = it.algorithm->sysReinitialize();
181  if ( rc.isFailure() ) {
182  this->error() << "Unable to re-initialize algorithm: " << it.algorithm->name() << endmsg;
183  return rc;
184  }
185  }
186  return rc;
187 }
188 
191  m_aess = serviceLocator()->service( "AlgExecStateSvc" );
192  if ( !m_aess.isValid() ) {
193  fatal() << "Error retrieving AlgExecStateSvc" << endmsg;
194  return StatusCode::FAILURE;
195  }
196 
197  StatusCode rc;
198 
199  for ( auto& it : m_algs ) {
200  if ( !it.managed ) continue;
201  rc = it.algorithm->sysRestart();
202  m_aess->resetErrorCount( it.algorithm );
203  if ( rc.isFailure() ) {
204  this->error() << "Unable to re-initialize algorithm: " << it.algorithm->name() << endmsg;
205  return rc;
206  }
207  }
208  return rc;
209 }
210 
212  resetMessaging();
213  for ( auto& algItem : m_algs ) {
214  const auto alg = dynamic_cast<Gaudi::Algorithm*>( algItem.algorithm.get() );
215  if ( alg ) alg->resetMessaging();
216  }
217 }
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).
Gaudi::StateMachine::State targetFSMState() const override
When we are in the middle of a transition, get the state where the transition is leading us.
StatusCode addAlgorithm(IAlgorithm *alg) override
implementation of IAlgManager::addAlgorithm
StatusCode start() override
Start (from INITIALIZED to RUNNING).
virtual StatusCode sysStart()=0
Startup method invoked by the framework.
AlgTypeAliasesMap m_algTypeAliases
std::vector< AlgorithmItem > m_algs
algorithms maintained by AlgorithmManager
const std::string & name() const override
Return the name of the manager (implementation of INamedInterface)
MSG::Level resetMessaging()
Reinitialize internal states.
bool isValid() const
Allow for check if smart pointer is valid.
Definition: SmartIF.h:72
constexpr static const auto SUCCESS
Definition: StatusCode.h:96
std::vector< IAlgorithm * > m_listOfPtrs
List of pointers to the know services used to implement getAlgorithms()
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:351
auto get(const Handle &handle, const Algo &, const EventContext &) -> decltype(details::deref(handle.get()))
bool existsAlgorithm(const std::string &name) const override
implementation of IAlgManager::existsAlgorithm
StatusCode stop() override
Stop (from RUNNING to INITIALIZED).
StatusCode finalize() override
Finalize (from INITIALIZED to CONFIGURED).
virtual StatusCode sysInitialize()=0
Initialization method invoked by the framework.
STL class.
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:86
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
Helper class to parse a string of format "type/name".
const std::vector< IAlgorithm * > & getAlgorithms() const override
implementation of IAlgManager::getAlgorithms
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:61
Definition of the basic interface.
Definition: IInterface.h:254
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:38
virtual void setType(const std::string &)=0
T find(T... args)
T size(T... args)
T begin(T... args)
T back_inserter(T... args)
constexpr static const auto FAILURE
Definition: StatusCode.h:97
SmartIF< ISvcLocator > & serviceLocator() const override
T substr(T... args)
AlgorithmManager(IInterface *iface)
default creator
SmartIF< IAlgorithm > & algorithm(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true) override
MsgStream & err() const
shortcut for the method msgStream(MSG::ERROR)
T transform(T... args)
GAUDI_API const std::string getLastErrorString()
Get last system error as string.
Definition: System.cpp:272
std::string typeName(const std::type_info &typ)
Definition: Dictionary.cpp:31
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
virtual void resetErrorCount(const IAlgorithm *iAlg)=0
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
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
T reserve(T... args)
StatusCode restart() override
Initialization (from RUNNING to RUNNING, via INITIALIZED).