All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups 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 // destructor
26 }
27 
28 // addAlgorithm
30  m_listalg.push_back(alg);
31  return StatusCode::SUCCESS;
32 }
33 
34 // removeAlgorithm
36  ListAlg::iterator it = std::find(m_listalg.begin(), m_listalg.end(), alg);
37  if (it != m_listalg.end()) {
38  m_listalg.erase(it);
39  return StatusCode::SUCCESS;
40  }
41  return StatusCode::FAILURE;
42 }
43 
44 // createService
45 StatusCode AlgorithmManager::createAlgorithm( const std::string& algtype,
46  const std::string& algname,
47  IAlgorithm*& algorithm,
48  bool managed)
49 {
50  // Check is the algorithm is already existing
51  if( existsAlgorithm( algname ) ) {
52  // return an error because an algorithm with that name already exists
53  return StatusCode::FAILURE;
54  }
55  std::string actualalgtype(algtype);
56  // a '\' in front of the type name prevents alias replacement
57  if ((actualalgtype.size() > 8) && (actualalgtype.substr(0, 8) == "unalias:")) {
58  actualalgtype = actualalgtype.substr(8);
59  } else {
60  AlgTypeAliasesMap::iterator typeAlias = m_algTypeAliases.find(algtype);
61  if (typeAlias != m_algTypeAliases.end()) {
62  actualalgtype = typeAlias->second;
63  }
64  }
65  algorithm = Algorithm::Factory::create(actualalgtype, algname, serviceLocator().get());
66  if ( algorithm ) {
67  // Check the compatibility of the version of the interface obtained
68  if( !isValidInterface(algorithm) ) {
69  fatal() << "Incompatible interface IAlgorithm version for " << actualalgtype << endmsg;
70  return StatusCode::FAILURE;
71  }
72  StatusCode rc;
73  m_listalg.push_back(AlgorithmItem(algorithm, managed));
74  // this is needed to keep the reference count correct, since isValidInterface(algorithm)
75  // implies an increment of the counter by 1
76  algorithm->release();
77  if ( managed ) {
78  // Bring the created algorithm to the same state of the ApplicationMgr
80  rc = algorithm->sysInitialize();
82  rc = algorithm->sysStart();
83  }
84  }
85  if ( !rc.isSuccess() ) {
86  this->error() << "Failed to initialize algorithm: [" << algname << "]" << endmsg;
87  }
88  }
89  return rc;
90  }
91  this->error() << "Algorithm of type " << actualalgtype
92  << " is unknown (No factory available)." << endmsg;
93 #ifndef _WIN32
94  errno = 0xAFFEDEAD; // code used by Gaudi for library load errors: forces getLastErrorString do use dlerror (on Linux)
95 #endif
96  std::string err = System::getLastErrorString();
97  if (! err.empty()) {
98  this->error() << err << endmsg;
99  }
100  this->error() << "More information may be available by setting the global jobOpt \"PluginDebugLevel\" to 1" << endmsg;
101 
102  return StatusCode::FAILURE;
103 }
104 
105 SmartIF<IAlgorithm>& AlgorithmManager::algorithm(const Gaudi::Utils::TypeNameString &typeName, const bool createIf) {
106  ListAlg::iterator it = std::find(m_listalg.begin(), m_listalg.end(), typeName.name());
107  if (it != m_listalg.end()) { // found
108  return it->algorithm;
109  }
110  if (createIf) {
111  IAlgorithm* alg;
112  if (createAlgorithm(typeName.type(), typeName.name(), alg, true).isSuccess()) {
113  return algorithm(typeName, false);
114  }
115  }
116  return no_algorithm;
117 }
118 
119 // existsAlgorithm
120 bool AlgorithmManager::existsAlgorithm(const std::string& name) const {
121  ListAlg::const_iterator it = std::find(m_listalg.begin(), m_listalg.end(), name);
122  return it != m_listalg.end();
123 }
124 
125  // Return the list of Algorithms
126 const std::vector<IAlgorithm*>& AlgorithmManager::getAlgorithms() const
127 {
128  m_listOfPtrs.clear();
129  m_listOfPtrs.reserve(m_listalg.size());
130  std::transform( std::begin(m_listalg), std::end(m_listalg),
131  std::back_inserter(m_listOfPtrs),
132  [](ListAlg::const_reference alg) {
133  return const_cast<IAlgorithm*>(alg.algorithm.get());
134  } );
135  return m_listOfPtrs;
136 }
137 
139  StatusCode rc;
140  ListAlg::iterator it;
141  for (it = m_listalg.begin(); it != m_listalg.end(); ++it) {
142  if (!it->managed) continue;
143  rc = it->algorithm->sysInitialize();
144  if ( rc.isFailure() ) return rc;
145  }
146  return rc;
147 }
148 
150  StatusCode rc;
151  ListAlg::iterator it;
152  for (it = m_listalg.begin(); it != m_listalg.end(); ++it) {
153  if (!it->managed) continue;
154  rc = it->algorithm->sysStart();
155  if ( rc.isFailure() ) return rc;
156  }
157  return rc;
158 }
159 
161  StatusCode rc;
162  ListAlg::iterator it;
163  for (it = m_listalg.begin(); it != m_listalg.end(); ++it) {
164  if (!it->managed) continue;
165  rc = it->algorithm->sysStop();
166  if ( rc.isFailure() ) return rc;
167  }
168  return rc;
169 }
170 
172  StatusCode rc;
173  ListAlg::iterator it = m_listalg.begin();
174  while (it != m_listalg.end()){ // finalize and remove from the list the managed algorithms
175  if (it->managed) {
176  rc = it->algorithm->sysFinalize();
177  if( rc.isFailure() ) return rc;
178  it = m_listalg.erase(it);
179  } else {
180  ++it;
181  }
182  }
183  return rc;
184 }
185 
187  StatusCode rc;
188  ListAlg::iterator it;
189  for (it = m_listalg.begin(); it != m_listalg.end(); ++it) {
190  if (!it->managed) continue;
191  rc = it->algorithm->sysReinitialize();
192  if( rc.isFailure() ){
193  this->error() << "Unable to re-initialize algorithm: " << it->algorithm->name() << endmsg;
194  return rc;
195  }
196  }
197  return rc;
198 }
199 
201  StatusCode rc;
202  ListAlg::iterator it;
203  for (it = m_listalg.begin(); it != m_listalg.end(); ++it) {
204  if (!it->managed) continue;
205  rc = it->algorithm->sysRestart();
206  if( rc.isFailure() ){
207  this->error() << "Unable to re-initialize algorithm: " << it->algorithm->name() << endmsg;
208  return rc;
209  }
210  }
211  return rc;
212 }