The Gaudi Framework  master (37c0b60a)
Bootstrap.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 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 <iostream>
12 
13 #include <GaudiKernel/Bootstrap.h>
14 #include <GaudiKernel/System.h>
15 
16 #include <GaudiKernel/IAlgorithm.h>
17 #include <GaudiKernel/IAppMgrUI.h>
19 #include <GaudiKernel/IInterface.h>
20 #include <GaudiKernel/IService.h>
22 
23 #include <Gaudi/Algorithm.h>
25 #include <GaudiKernel/Service.h>
26 
28 
29 #include <RVersion.h>
30 
31 #include <Python.h>
32 
33 namespace Gaudi {
34 
50  class BootSvcLocator : public implements<ISvcLocator> {
51  public:
52 #if !defined( GAUDI_V22_API ) || defined( G22_NEW_SVCLOCATOR )
54  IInterface*& pinterface ) override;
56  const bool createIf = true ) override;
57 #endif
58  const std::list<IService*>& getServices() const override;
59  bool existsService( std::string_view name ) const override;
60 
62  SmartIF<IService>& service( const Gaudi::Utils::TypeNameString& typeName, const bool createIf = true ) override;
63  };
64 } // namespace Gaudi
65 
66 static SmartIF<ISvcLocator> s_svclocInstance;
67 static SmartIF<IAppMgrUI> s_appmgrInstance;
68 
69 //------------------------------------------------------------------------------
70 IAppMgrUI* Gaudi::createApplicationMgr( const std::string& dllname, const std::string& factname )
71 //------------------------------------------------------------------------------
72 {
73  // Allow not for multiple AppManagers: If already instantiated then just
74  // return it
75  if ( !s_appmgrInstance ) {
76  s_appmgrInstance = createApplicationMgrEx( dllname, factname );
77  s_svclocInstance = s_appmgrInstance;
78  }
79  return s_appmgrInstance.get();
80 }
81 
82 //------------------------------------------------------------------------------
83 IAppMgrUI* Gaudi::createApplicationMgrEx( const std::string& dllname, const std::string& factname )
84 //------------------------------------------------------------------------------
85 {
86  // Create an instance of the application Manager
87  auto iif = make_SmartIF( Gaudi::createInstance( "ApplicationMgr", factname, dllname ) );
88  // Locate few interfaces of the Application Manager
89  return iif ? iif.as<IAppMgrUI>().get() : nullptr;
90 }
91 
92 //------------------------------------------------------------------------------
94 //------------------------------------------------------------------------------
95 //
96 // A dual-stage bootstrap mechanism is used to ensure an orderly startup
97 // of the ApplicationMgr. If this function is called before the singleton
98 // ApplicationMgr instance exists, a BootSvcLocator singleton instance is
99 // created. This responds to any subsequent requests for services by
100 // returning StatusCode::FAILURE, unless the ApplicationMgr singleton
101 // instance has been created in the interim. In this case, the BootSvcLocator
102 // forwards the request to the ApplicationMgr instance. The motivation for
103 // this is to handle static object instances where the constructor attempts
104 // to locate services and would otherwise instantiate the ApplicationMgr
105 // instance in an unorderly manner. This logic requires that the
106 // ApplicationMgr instance is created explicitly.
107 
108 {
109  if ( !s_svclocInstance ) {
110  IAppMgrUI* iappmgr = createApplicationMgr();
111  if ( iappmgr ) {
112  s_svclocInstance = iappmgr;
113  if ( s_svclocInstance ) return s_svclocInstance;
114  }
115  //---Reverted change to create a Minimal SvcLocator in case is requested before AppMgr is created
116  // if( 0 == s_appmgrInstance ) {
117  // s_svclocInstance = new BootSvcLocator();
118  //} else {
119  // StatusCode sc = s_appmgrInstance->queryInterface( ISvcLocator::interfaceID(),
120  // pp_cast<void>(&s_svclocInstance) );
121  // if( sc.isSuccess() ) {
122  // return s_svclocInstance;
123  // }
124  //}
125  }
126  return s_svclocInstance;
127 }
128 
129 //------------------------------------------------------------------------------
131 //------------------------------------------------------------------------------
132 {
133  ISvcLocator* oldInstance = s_svclocInstance.get();
134  s_svclocInstance = newInstance;
135  s_appmgrInstance = s_svclocInstance;
136  return oldInstance;
137 }
138 
139 //------------------------------------------------------------------------------
140 IAppMgrUI* Gaudi::setInstance( IAppMgrUI* newInstance )
141 //------------------------------------------------------------------------------
142 {
143  IAppMgrUI* oldInstance = s_appmgrInstance.get();
144  s_appmgrInstance = newInstance;
145  s_svclocInstance = s_appmgrInstance;
146  return oldInstance;
147 }
148 
149 //------------------------------------------------------------------------------
150 IInterface* Gaudi::createInstance( const std::string& name, const std::string& factname, const std::string& dllname )
151 //------------------------------------------------------------------------------
152 {
153 
154  IInterface* ii = ObjFactory::create( factname, nullptr ).release();
155  if ( ii ) return ii;
156  IService* is = Service::Factory::create( factname, name, nullptr ).release();
157  if ( is ) return is;
158  IAlgorithm* ia = Algorithm::Factory::create( factname, name, nullptr ).release();
159  if ( ia ) return ia;
160 
161  void* libHandle = nullptr;
162  if ( System::loadDynamicLib( dllname, &libHandle ) ) {
163  ii = ObjFactory::create( factname, nullptr ).release();
164  if ( ii ) return ii;
165  is = Service::Factory::create( factname, name, nullptr ).release();
166  if ( is ) return is;
167  ia = Algorithm::Factory::create( factname, name, nullptr ).release();
168  if ( ia ) return ia;
169  } else {
170  // DLL library not loaded. Try in the local module
172  std::cout << "Gaudi::Bootstrap: Not found DLL " << dllname << std::endl;
173  }
174  return nullptr;
175 }
176 
177 //------------------------------------------------------------------------------
179  //------------------------------------------------------------------------------
180  return createApplicationMgr( dllname, "ApplicationMgr" );
181 }
182 
183 //------------------------------------------------------------------------------
185  //------------------------------------------------------------------------------
186  return createApplicationMgr( "GaudiCoreSvc", "ApplicationMgr" );
187 }
188 
189 //=======================================================================
190 // BootSvcLocator
191 //=======================================================================
192 
193 static std::list<IService*> s_bootServices;
194 static SmartIF<IService> s_bootService;
195 static SmartIF<IInterface> s_bootInterface;
196 
198 
199 #if !defined( GAUDI_V22_API ) || defined( G22_NEW_SVCLOCATOR )
200 # pragma GCC diagnostic push
201 # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
203  IInterface*& pinterface ) {
205  if ( s_appmgrInstance ) {
206  sc = s_svclocInstance->getService( typeName, iid, pinterface );
207  } else {
208  pinterface = s_bootInterface.get();
209  }
210  return sc;
211 }
213  const bool createIf ) {
215  if ( s_appmgrInstance ) {
216  sc = s_svclocInstance->getService( typeName, svc, createIf );
217  } else {
218  svc = s_bootService.get();
219  }
220  return sc;
221 }
222 # pragma GCC diagnostic pop
223 #endif
224 
226  return s_appmgrInstance ? s_svclocInstance->getServices() : s_bootServices;
227 }
228 bool Gaudi::BootSvcLocator::existsService( std::string_view name ) const {
229  return s_appmgrInstance && s_svclocInstance->existsService( name );
230 }
231 
233  return s_appmgrInstance ? s_svclocInstance->service( typeName, createIf ) : s_bootService;
234 }
235 
236 #ifdef GAUDI_HASCLASSVISIBILITY
237 # pragma GCC visibility push( default )
238 #endif
239 // Python bootstrap helpers
240 extern "C" {
241 #define PyHelper( x ) py_bootstrap_##x
244  auto svcloc = SmartIF<ISvcLocator>( app );
245  return svcloc ? svcloc->service<IInterface>( std::string_view{ name } ).get() : nullptr;
246 }
247 bool PyHelper( setProperty )( IInterface* p, char* name, char* value ) {
248  auto prop = SmartIF<IProperty>( p );
249  return prop && prop->setProperty( name, value ).isSuccess();
250 }
251 const char* PyHelper( getProperty )( IInterface* p, char* name ) {
252  auto prop = SmartIF<IProperty>( p );
253  if ( !prop ) return nullptr;
254  // this is needed to guarantee that Python can access the returned char*
255  static std::string value;
256  value = prop->getProperty( name ).toString();
257  return value.c_str();
258 }
259 void PyHelper( setOption )( IInterface* app, char* key, char* value ) {
260  if ( auto svcloc = SmartIF<ISvcLocator>( app ) ) { svcloc->getOptsSvc().set( key, value ); }
261 }
263  auto ui = SmartIF<IAppMgrUI>( app );
264  return ui && ui->configure().isSuccess();
265 }
267 
268 bool py_bootstrap_app_run( IInterface* i, int maxevt ) {
269  auto ep = SmartIF<IEventProcessor>( i );
270  bool stat = false;
271  // Relinquish the GIL to allow python algs in MT mode
272  Py_BEGIN_ALLOW_THREADS;
273  stat = ep && ep->executeRun( maxevt ).isSuccess();
274  Py_END_ALLOW_THREADS;
275  return stat;
276 }
277 
278 #define PyFSMHelper( s ) \
279  bool py_bootstrap_fsm_##s( IInterface* i ) { \
280  auto fsm = SmartIF<IStateful>( i ); \
281  return fsm && fsm->s().isSuccess(); \
282  }
283 
284 // clang-format off
286 PyFSMHelper( initialize )
288 PyFSMHelper( stop )
289 PyFSMHelper( finalize )
290 PyFSMHelper( terminate )
291 // clang-format on
292 }
293 #ifdef GAUDI_HASCLASSVISIBILITY
294 # pragma GCC visibility pop
295 #endif
IService
Definition: IService.h:28
Gaudi::createInstance
GAUDI_API IInterface * createInstance(const std::string &name, const std::string &factname, const std::string &ddlname)
Gaudi::createApplicationMgr
GAUDI_API IAppMgrUI * createApplicationMgr(const std::string &dllname, const std::string &factname)
System::loadDynamicLib
GAUDI_API unsigned long loadDynamicLib(const std::string &name, ImageHandle *handle)
Load dynamic link library.
Definition: System.cpp:150
IService.h
std::string
STL class.
setProperty
bool PyHelper() setProperty(IInterface *p, char *name, char *value)
Definition: Bootstrap.cpp:247
std::list< IService * >
Read.app
app
Definition: Read.py:36
System.h
ISvcLocator
Definition: ISvcLocator.h:46
GaudiPartProp.decorators.get
get
decorate the vector of properties
Definition: decorators.py:283
py_bootstrap_app_run
bool py_bootstrap_app_run(IInterface *i, int maxevt)
Definition: Bootstrap.cpp:268
getService
IInterface *PyHelper() getService(IInterface *app, char *name)
Definition: Bootstrap.cpp:243
ObjectFactory.h
configureApp
bool PyHelper() configureApp(IInterface *app)
Definition: Bootstrap.cpp:262
IOTest.start
start
Definition: IOTest.py:110
IAppMgrUI.h
Gaudi::createApplicationMgrEx
GAUDI_API IAppMgrUI * createApplicationMgrEx(const std::string &dllname, const std::string &factname)
Gaudi::BootSvcLocator::service
SmartIF< IService > & service(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true) override
Returns a smart pointer to a service.
Definition: Bootstrap.cpp:232
PyHelper
#define PyHelper(x)
Definition: Bootstrap.cpp:241
Gaudi::svcLocator
GAUDI_API ISvcLocator * svcLocator()
Gaudi::Utils::TypeNameString
Helper class to parse a string of format "type/name".
Definition: TypeNameString.h:20
IClassManager.h
StatusCode
Definition: StatusCode.h:65
IInterface.h
IAlgorithm
Definition: IAlgorithm.h:38
std::cout
std::string::c_str
T c_str(T... args)
Gaudi::setInstance
GAUDI_API ISvcLocator * setInstance(ISvcLocator *newInstance)
Set new instance of service locator.
Gaudi::BootSvcLocator
Definition: Bootstrap.cpp:50
GaudiPython.Bindings.nullptr
nullptr
Definition: Bindings.py:87
Algorithm.h
SmartIF< IService >
Gaudi
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition: __init__.py:1
Service.h
ROOT_VERSION_CODE
int PyHelper() ROOT_VERSION_CODE()
Definition: Bootstrap.cpp:266
PyFSMHelper
#define PyFSMHelper(s)
Definition: Bootstrap.cpp:278
implements
Base class used to implement the interfaces.
Definition: implements.h:19
IAppMgrUI
Definition: IAppMgrUI.h:34
make_SmartIF
SmartIF< IFace > make_SmartIF(IFace *iface)
Definition: SmartIF.h:150
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
std::endl
T endl(T... args)
SmartIF::get
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:86
GaudiDict::typeName
std::string typeName(const std::type_info &typ)
Definition: Dictionary.cpp:31
IInterface
Definition: IInterface.h:239
Bootstrap.h
ExtendedProperties.configure
def configure(gaudi=None)
Definition: ExtendedProperties.py:40
Gaudi::BootSvcLocator::getService
StatusCode getService(const Gaudi::Utils::TypeNameString &typeName, const InterfaceID &iid, IInterface *&pinterface) override
Definition: Bootstrap.cpp:202
InterfaceID
Definition: IInterface.h:39
IAlgorithm.h
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
getProperty
const char *PyHelper() getProperty(IInterface *p, char *name)
Definition: Bootstrap.cpp:251
IInterface::release
virtual unsigned long release()=0
Release Interface instance.
ISvcLocator.h
Gaudi::BootSvcLocator::existsService
bool existsService(std::string_view name) const override
Definition: Bootstrap.cpp:228
System::getLastErrorString
GAUDI_API const std::string getLastErrorString()
Get last system error as string.
Definition: System.cpp:279
ProduceConsume.key
key
Definition: ProduceConsume.py:84
IEventProcessor.h
setOption
void PyHelper() setOption(IInterface *app, char *key, char *value)
Definition: Bootstrap.cpp:259
Gaudi::BootSvcLocator::getServices
const std::list< IService * > & getServices() const override
Definition: Bootstrap.cpp:225