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 {
46  // Check is the algorithm is already existing
47  if( existsAlgorithm( algname ) ) {
48  // return an error because an algorithm with that name already exists
49  return StatusCode::FAILURE;
50  }
51  std::string actualalgtype(algtype);
52  // a '\' in front of the type name prevents alias replacement
53  if ((actualalgtype.size() > 8) && (actualalgtype.compare(0, 8,"unalias:") == 0)) {
54  actualalgtype = actualalgtype.substr(8);
55  } else {
56  auto typeAlias = m_algTypeAliases.find(algtype);
57  if (typeAlias != m_algTypeAliases.end()) {
58  actualalgtype = typeAlias->second;
59  }
60  }
61  algorithm = Algorithm::Factory::create(actualalgtype, algname, serviceLocator().get());
62  if ( !algorithm ) {
63  this->error() << "Algorithm of type " << actualalgtype
64  << " is unknown (No factory available)." << endmsg;
65 #ifndef _WIN32
66  errno = 0xAFFEDEAD; // code used by Gaudi for library load errors: forces getLastErrorString do use dlerror (on Linux)
67 #endif
68  std::string err = System::getLastErrorString();
69  if (! err.empty()) this->error() << err << endmsg;
70  this->error() << "More information may be available by setting the global jobOpt \"PluginDebugLevel\" to 1" << endmsg;
71  return StatusCode::FAILURE;
72  }
73  // Check the compatibility of the version of the interface obtained
74  if( !isValidInterface(algorithm) ) {
75  fatal() << "Incompatible interface IAlgorithm version for " << actualalgtype << endmsg;
76  return StatusCode::FAILURE;
77  }
78  m_algs.emplace_back(algorithm, managed);
79  // this is needed to keep the reference count correct, since isValidInterface(algorithm)
80  // implies an increment of the counter by 1
81  algorithm->release();
82  StatusCode rc;
83  if ( managed ) {
84  // Bring the created algorithm to the same state of the ApplicationMgr
85  if (FSMState() >= Gaudi::StateMachine::INITIALIZED) {
86  rc = algorithm->sysInitialize();
87  if (rc.isSuccess() && FSMState() >= Gaudi::StateMachine::RUNNING) {
88  rc = algorithm->sysStart();
89  }
90  }
91  if ( !rc.isSuccess() ) {
92  this->error() << "Failed to initialize algorithm: [" << algname << "]" << endmsg;
93  }
94  }
95  return rc;
96 }
97 
99  auto it = std::find(m_algs.begin(), m_algs.end(), typeName.name());
100  if (it != m_algs.end()) { // found
101  return it->algorithm;
102  }
103  if (createIf) {
104  IAlgorithm* alg;
105  if (createAlgorithm(typeName.type(), typeName.name(), alg, true).isSuccess()) {
106  return algorithm(typeName, false);
107  }
108  }
109  return no_algorithm;
110 }
111 
112 // existsAlgorithm
113 bool AlgorithmManager::existsAlgorithm(const std::string& name) const {
114  return m_algs.end() != std::find(m_algs.begin(), m_algs.end(), name);
115 }
116 
117  // Return the list of Algorithms
118 const std::vector<IAlgorithm*>& AlgorithmManager::getAlgorithms() const
119 {
120  m_listOfPtrs.clear();
121  m_listOfPtrs.reserve(m_algs.size());
122  std::transform( std::begin(m_algs), std::end(m_algs),
123  std::back_inserter(m_listOfPtrs),
124  [](const AlgorithmItem& alg) {
125  return const_cast<IAlgorithm*>(alg.algorithm.get());
126  } );
127  return m_listOfPtrs;
128 }
129 
131  StatusCode rc;
132  for (auto& it : m_algs ) {
133  if (!it.managed) continue;
134  rc = it.algorithm->sysInitialize();
135  if ( rc.isFailure() ) return rc;
136  }
137  return rc;
138 }
139 
141  StatusCode rc;
142  for (auto& it : m_algs ) {
143  if (!it.managed) continue;
144  rc = it.algorithm->sysStart();
145  if ( rc.isFailure() ) return rc;
146  }
147  return rc;
148 }
149 
151  StatusCode rc;
152  for (auto& it : m_algs) {
153  if (!it.managed) continue;
154  rc = it.algorithm->sysStop();
155  if ( rc.isFailure() ) return rc;
156  }
157  return rc;
158 }
159 
161  StatusCode rc;
162  auto it = m_algs.begin();
163  while (it != m_algs.end()){ // finalize and remove from the list the managed algorithms
164  if (it->managed) {
165  rc = it->algorithm->sysFinalize();
166  if( rc.isFailure() ) return rc;
167  it = m_algs.erase(it);
168  } else {
169  ++it;
170  }
171  }
172  return rc;
173 }
174 
176  StatusCode rc;
177  for (auto& it : m_algs ) {
178  if (!it.managed) continue;
179  rc = it.algorithm->sysReinitialize();
180  if( rc.isFailure() ){
181  this->error() << "Unable to re-initialize algorithm: " << it.algorithm->name() << endmsg;
182  return rc;
183  }
184  }
185  return rc;
186 }
187 
189  StatusCode rc;
190  for (auto& it : m_algs ) {
191  if (!it.managed) continue;
192  rc = it.algorithm->sysRestart();
193  if( rc.isFailure() ){
194  this->error() << "Unable to re-initialize algorithm: " << it.algorithm->name() << endmsg;
195  return rc;
196  }
197  }
198  return rc;
199 }
bool isValidInterface(I *i)
Templated function that throws an exception if the version if the interface implemented by the object...
Definition: IInterface.h:323
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).
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)
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:76
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:19
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
const std::string & name() const
std::string typeName(const std::type_info &typ)
Definition: Dictionary.cpp:21
SmartIF< IAlgorithm > algorithm
StatusCode createAlgorithm(const std::string &algtype, const std::string &algname, IAlgorithm *&algorithm, bool managed=false) override
implementation of IAlgManager::createAlgorithm
StatusCode restart() override
Initialization (from RUNNING to RUNNING, via INITIALIZED).