The Gaudi Framework  master (42b00024)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Bootstrap.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2025 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  const std::list<IService*>& getServices() const override;
53  bool existsService( std::string_view name ) const override;
54 
56  SmartIF<IService>& service( const Gaudi::Utils::TypeNameString& typeName, const bool createIf = true ) override;
57  };
58 } // namespace Gaudi
59 
60 static SmartIF<ISvcLocator> s_svclocInstance;
61 static SmartIF<IAppMgrUI> s_appmgrInstance;
62 
63 //------------------------------------------------------------------------------
64 IAppMgrUI* Gaudi::createApplicationMgr( const std::string& dllname, const std::string& factname )
65 //------------------------------------------------------------------------------
66 {
67  // Allow not for multiple AppManagers: If already instantiated then just
68  // return it
69  if ( !s_appmgrInstance ) {
70  s_appmgrInstance = createApplicationMgrEx( dllname, factname );
71  s_svclocInstance = s_appmgrInstance;
72  }
73  return s_appmgrInstance.get();
74 }
75 
76 //------------------------------------------------------------------------------
77 IAppMgrUI* Gaudi::createApplicationMgrEx( const std::string& dllname, const std::string& factname )
78 //------------------------------------------------------------------------------
79 {
80  // Create an instance of the application Manager
81  auto iif = make_SmartIF( Gaudi::createInstance( "ApplicationMgr", factname, dllname ) );
82  // Locate few interfaces of the Application Manager
83  return iif ? iif.as<IAppMgrUI>().get() : nullptr;
84 }
85 
86 //------------------------------------------------------------------------------
88 //------------------------------------------------------------------------------
89 //
90 // A dual-stage bootstrap mechanism is used to ensure an orderly startup
91 // of the ApplicationMgr. If this function is called before the singleton
92 // ApplicationMgr instance exists, a BootSvcLocator singleton instance is
93 // created. This responds to any subsequent requests for services by
94 // returning StatusCode::FAILURE, unless the ApplicationMgr singleton
95 // instance has been created in the interim. In this case, the BootSvcLocator
96 // forwards the request to the ApplicationMgr instance. The motivation for
97 // this is to handle static object instances where the constructor attempts
98 // to locate services and would otherwise instantiate the ApplicationMgr
99 // instance in an unorderly manner. This logic requires that the
100 // ApplicationMgr instance is created explicitly.
101 
102 {
103  if ( !s_svclocInstance ) {
104  IAppMgrUI* iappmgr = createApplicationMgr();
105  if ( iappmgr ) {
106  s_svclocInstance = iappmgr;
107  if ( s_svclocInstance ) return s_svclocInstance;
108  }
109  //---Reverted change to create a Minimal SvcLocator in case is requested before AppMgr is created
110  // if( 0 == s_appmgrInstance ) {
111  // s_svclocInstance = new BootSvcLocator();
112  //} else {
113  // StatusCode sc = s_appmgrInstance->queryInterface( ISvcLocator::interfaceID(),
114  // pp_cast<void>(&s_svclocInstance) );
115  // if( sc.isSuccess() ) {
116  // return s_svclocInstance;
117  // }
118  //}
119  }
120  return s_svclocInstance;
121 }
122 
123 //------------------------------------------------------------------------------
125 //------------------------------------------------------------------------------
126 {
127  ISvcLocator* oldInstance = s_svclocInstance.get();
128  s_svclocInstance = newInstance;
129  s_appmgrInstance = s_svclocInstance;
130  return oldInstance;
131 }
132 
133 //------------------------------------------------------------------------------
134 IAppMgrUI* Gaudi::setInstance( IAppMgrUI* newInstance )
135 //------------------------------------------------------------------------------
136 {
137  IAppMgrUI* oldInstance = s_appmgrInstance.get();
138  s_appmgrInstance = newInstance;
139  s_svclocInstance = s_appmgrInstance;
140  return oldInstance;
141 }
142 
143 //------------------------------------------------------------------------------
144 IInterface* Gaudi::createInstance( const std::string& name, const std::string& factname, const std::string& dllname )
145 //------------------------------------------------------------------------------
146 {
147 
148  IInterface* ii = ObjFactory::create( factname, nullptr ).release();
149  if ( ii ) return ii;
150  IService* is = Service::Factory::create( factname, name, nullptr ).release();
151  if ( is ) return is;
152  IAlgorithm* ia = Algorithm::Factory::create( factname, name, nullptr ).release();
153  if ( ia ) return ia;
154 
155  void* libHandle = nullptr;
156  if ( System::loadDynamicLib( dllname, &libHandle ) ) {
157  ii = ObjFactory::create( factname, nullptr ).release();
158  if ( ii ) return ii;
159  is = Service::Factory::create( factname, name, nullptr ).release();
160  if ( is ) return is;
161  ia = Algorithm::Factory::create( factname, name, nullptr ).release();
162  if ( ia ) return ia;
163  } else {
164  // DLL library not loaded. Try in the local module
165  std::cout << System::getLastErrorString() << std::endl;
166  std::cout << "Gaudi::Bootstrap: Not found DLL " << dllname << std::endl;
167  }
168  return nullptr;
169 }
170 
171 //------------------------------------------------------------------------------
172 IAppMgrUI* Gaudi::createApplicationMgr( const std::string& dllname ) {
173  //------------------------------------------------------------------------------
174  return createApplicationMgr( dllname, "ApplicationMgr" );
175 }
176 
177 //------------------------------------------------------------------------------
179  //------------------------------------------------------------------------------
180  return createApplicationMgr( "GaudiCoreSvc", "ApplicationMgr" );
181 }
182 
183 //=======================================================================
184 // BootSvcLocator
185 //=======================================================================
186 
187 static std::list<IService*> s_bootServices;
188 static SmartIF<IService> s_bootService;
189 static SmartIF<IInterface> s_bootInterface;
190 
192 
193 const std::list<IService*>& Gaudi::BootSvcLocator::getServices() const {
194  return s_appmgrInstance ? s_svclocInstance->getServices() : s_bootServices;
195 }
196 bool Gaudi::BootSvcLocator::existsService( std::string_view name ) const {
197  return s_appmgrInstance && s_svclocInstance->existsService( name );
198 }
199 
201  return s_appmgrInstance ? s_svclocInstance->service( typeName, createIf ) : s_bootService;
202 }
203 
204 #ifdef GAUDI_HASCLASSVISIBILITY
205 # pragma GCC visibility push( default )
206 #endif
207 // Python bootstrap helpers
208 extern "C" {
209 #define PyHelper( x ) py_bootstrap_##x
212  auto svcloc = SmartIF<ISvcLocator>( app );
213  return svcloc ? svcloc->service<IInterface>( std::string_view{ name } ).get() : nullptr;
214 }
215 bool PyHelper( setProperty )( IInterface* p, char* name, char* value ) {
216  auto prop = SmartIF<IProperty>( p );
217  return prop && prop->setProperty( name, value ).isSuccess();
218 }
219 const char* PyHelper( getProperty )( IInterface* p, char* name ) {
220  auto prop = SmartIF<IProperty>( p );
221  if ( !prop ) return nullptr;
222  // this is needed to guarantee that Python can access the returned char*
223  static std::string value;
224  value = prop->getProperty( name ).toString();
225  return value.c_str();
226 }
227 void PyHelper( setOption )( IInterface* app, char* key, char* value ) {
228  if ( auto svcloc = SmartIF<ISvcLocator>( app ) ) { svcloc->getOptsSvc().set( key, value ); }
229 }
231  auto ui = SmartIF<IAppMgrUI>( app );
232  return ui && ui->configure().isSuccess();
233 }
235 
236 bool py_bootstrap_app_run( IInterface* i, int maxevt ) {
237  auto ep = SmartIF<IEventProcessor>( i );
238  bool stat = false;
239  // Relinquish the GIL to allow python algs in MT mode
240  Py_BEGIN_ALLOW_THREADS;
241  stat = ep && ep->executeRun( maxevt ).isSuccess();
242  Py_END_ALLOW_THREADS;
243  return stat;
244 }
245 
246 #define PyFSMHelper( s ) \
247  bool py_bootstrap_fsm_##s( IInterface* i ) { \
248  auto fsm = SmartIF<IStateful>( i ); \
249  return fsm && fsm->s().isSuccess(); \
250  }
251 
252 // clang-format off
254 PyFSMHelper( initialize )
256 PyFSMHelper( stop )
257 PyFSMHelper( finalize )
258 PyFSMHelper( terminate )
259 // clang-format on
260 }
261 #ifdef GAUDI_HASCLASSVISIBILITY
262 # pragma GCC visibility pop
263 #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
setProperty
bool PyHelper() setProperty(IInterface *p, char *name, char *value)
Definition: Bootstrap.cpp:215
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:236
getService
IInterface *PyHelper() getService(IInterface *app, char *name)
Definition: Bootstrap.cpp:211
ObjectFactory.h
configureApp
bool PyHelper() configureApp(IInterface *app)
Definition: Bootstrap.cpp:230
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:200
PyHelper
#define PyHelper(x)
Definition: Bootstrap.cpp:209
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
IInterface.h
IAlgorithm
Definition: IAlgorithm.h:38
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:234
PyFSMHelper
#define PyFSMHelper(s)
Definition: Bootstrap.cpp:246
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:146
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
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:226
Bootstrap.h
ExtendedProperties.configure
def configure(gaudi=None)
Definition: ExtendedProperties.py:40
IAlgorithm.h
getProperty
const char *PyHelper() getProperty(IInterface *p, char *name)
Definition: Bootstrap.cpp:219
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:196
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:227
Gaudi::BootSvcLocator::getServices
const std::list< IService * > & getServices() const override
Definition: Bootstrap.cpp:193