All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
AlgorithmManager.cpp
Go to the documentation of this file.
1 // Include files
2 #include "AlgorithmManager.h"
3 #include "GaudiKernel/IAlgorithm.h"
4 #include "GaudiKernel/Algorithm.h"
5 #include "GaudiKernel/ISvcLocator.h"
6 #include "GaudiKernel/System.h"
7 #include "GaudiKernel/MsgStream.h"
8 #include "GaudiKernel/TypeNameString.h"
9 #include <iostream>
10 #ifndef _WIN32
11 #include <errno.h>
12 #endif
13 
15 static SmartIF<IAlgorithm> no_algorithm;
16 
17 // constructor
19  base_class(application, IAlgorithm::interfaceID())
20 {
21  addRef(); // Initial count set to 1
22 }
23 
24 // addAlgorithm
26  m_algs.push_back(alg);
27  return StatusCode::SUCCESS;
28 }
29 
30 // removeAlgorithm
32  auto it = std::find(m_algs.begin(), m_algs.end(), alg);
33  if (it != m_algs.end()) {
34  m_algs.erase(it);
35  return StatusCode::SUCCESS;
36  }
37  return StatusCode::FAILURE;
38 }
39 
40 // createService
41 StatusCode AlgorithmManager::createAlgorithm( const std::string& algtype,
42  const std::string& algname,
43  IAlgorithm*& algorithm,
44  bool managed,
45  bool checkIfExists)
46 {
47  // Check is the algorithm is already existing
48  if (checkIfExists) {
49  if( existsAlgorithm( algname ) ) {
50  // return an error because an algorithm with that name already exists
51  return StatusCode::FAILURE;
52  }
53  }
54  std::string actualalgtype(algtype);
55  // a '\' in front of the type name prevents alias replacement
56  if ((actualalgtype.size() > 8) && (actualalgtype.compare(0, 8,"unalias:") == 0)) {
57  actualalgtype = actualalgtype.substr(8);
58  } else {
59  auto typeAlias = m_algTypeAliases.find(algtype);
60  if (typeAlias != m_algTypeAliases.end()) {
61  actualalgtype = typeAlias->second;
62  }
63  }
64  algorithm = Algorithm::Factory::create(actualalgtype, algname, serviceLocator().get());
65  if ( !algorithm ) {
66  this->error() << "Algorithm of type " << actualalgtype
67  << " is unknown (No factory available)." << endmsg;
68 #ifndef _WIN32
69  errno = 0xAFFEDEAD; // code used by Gaudi for library load errors: forces getLastErrorString do use dlerror (on Linux)
70 #endif
71  std::string err = System::getLastErrorString();
72  if (! err.empty()) this->error() << err << endmsg;
73  this->error() << "More information may be available by setting the global jobOpt \"PluginDebugLevel\" to 1" << 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
90  if (FSMState() >= Gaudi::StateMachine::INITIALIZED) {
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  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
118 bool AlgorithmManager::existsAlgorithm(const std::string& name) const {
119  return m_algs.end() != std::find(m_algs.begin(), m_algs.end(), name);
120 }
121 
122  // Return the list of Algorithms
123 const std::vector<IAlgorithm*>& AlgorithmManager::getAlgorithms() const
124 {
125  m_listOfPtrs.clear();
126  m_listOfPtrs.reserve(m_algs.size());
127  std::transform( std::begin(m_algs), std::end(m_algs),
128  std::back_inserter(m_listOfPtrs),
129  [](const AlgorithmItem& alg) {
130  return const_cast<IAlgorithm*>(alg.algorithm.get());
131  } );
132  return m_listOfPtrs;
133 }
134 
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  StatusCode rc;
147  for (auto& it : m_algs ) {
148  if (!it.managed) continue;
149  rc = it.algorithm->sysStart();
150  if ( rc.isFailure() ) return rc;
151  }
152  return rc;
153 }
154 
156  StatusCode rc;
157  for (auto& it : m_algs) {
158  if (!it.managed) continue;
159  rc = it.algorithm->sysStop();
160  if ( rc.isFailure() ) return rc;
161  }
162  return rc;
163 }
164 
166  StatusCode rc;
167  auto it = m_algs.begin();
168  while (it != m_algs.end()){ // finalize and remove from the list the managed algorithms
169  if (it->managed) {
170  rc = it->algorithm->sysFinalize();
171  if( rc.isFailure() ) return rc;
172  it = m_algs.erase(it);
173  } else {
174  ++it;
175  }
176  }
177  return rc;
178 }
179 
181  StatusCode rc;
182  for (auto& it : m_algs ) {
183  if (!it.managed) continue;
184  rc = it.algorithm->sysReinitialize();
185  if( rc.isFailure() ){
186  this->error() << "Unable to re-initialize algorithm: " << it.algorithm->name() << endmsg;
187  return rc;
188  }
189  }
190  return rc;
191 }
192 
194  StatusCode rc;
195  for (auto& it : m_algs ) {
196  if (!it.managed) continue;
197  rc = it.algorithm->sysRestart();
198  if( rc.isFailure() ){
199  this->error() << "Unable to re-initialize algorithm: " << it.algorithm->name() << endmsg;
200  return rc;
201  }
202  }
203  return rc;
204 }
StatusCode initialize() override
Initialization (from CONFIGURED to INITIALIZED).
StatusCode addAlgorithm(IAlgorithm *alg) override
implementation of IAlgManager::addAlgorithm
StatusCode start() override
Start (from INITIALIZED to RUNNING).
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
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)
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:76
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
std::vector< IAlgorithm * > m_listOfPtrs
List of pointers to the know services used to implement getAlgorithms()
StatusCode reinitialize() override
Initialization (from INITIALIZED or RUNNING to INITIALIZED, via CONFIGURED).
bool existsAlgorithm(const std::string &name) const override
implementation of IAlgManager::existsAlgorithm
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
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.
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:76
Helper class to parse a string of format "type/name".
Definition: TypeNameString.h:9
const std::vector< IAlgorithm * > & getAlgorithms() const override
implementation of IAlgManager::getAlgorithms
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
Definition of the basic interface.
Definition: IInterface.h:234
StatusCode removeAlgorithm(IAlgorithm *alg) override
implementation of IAlgManager::removeAlgorithm
tuple rc
Definition: IOTest.py:92
The IAlgorithm is the interface implemented by the Algorithm base class.
Definition: IAlgorithm.h:23
virtual void setType(const std::string &)=0
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
const std::string & type() const
GAUDI_API const std::string getLastErrorString()
Get last system error as string.
Definition: System.cpp:254
AlgorithmManager(IInterface *iface)
default creator
SmartIF< IAlgorithm > & algorithm(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true) override
bool isValidInterface(I *i)
Templated function that throws an exception if the version if the interface implemented by the object...
Definition: IInterface.h:323
const std::string & name() const
std::string typeName(const std::type_info &typ)
Definition: Dictionary.cpp:21
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
StatusCode restart() override
Initialization (from RUNNING to RUNNING, via INITIALIZED).