The Gaudi Framework  master (82fdf313)
Loading...
Searching...
No Matches
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
14#include <GaudiKernel/System.h>
15
22
23#include <Gaudi/Algorithm.h>
25#include <GaudiKernel/Service.h>
26
28
29#include <RVersion.h>
30
31#include <Python.h>
32
33namespace 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
60static SmartIF<ISvcLocator> s_svclocInstance;
61static SmartIF<IAppMgrUI> s_appmgrInstance;
62
63//------------------------------------------------------------------------------
64IAppMgrUI* 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//------------------------------------------------------------------------------
77IAppMgrUI* 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//------------------------------------------------------------------------------
135//------------------------------------------------------------------------------
136{
137 IAppMgrUI* oldInstance = s_appmgrInstance.get();
138 s_appmgrInstance = newInstance;
139 s_svclocInstance = s_appmgrInstance;
140 return oldInstance;
141}
142
143//------------------------------------------------------------------------------
144IInterface* 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//------------------------------------------------------------------------------
172IAppMgrUI* Gaudi::createApplicationMgr( const std::string& dllname ) {
173 //------------------------------------------------------------------------------
174 return createApplicationMgr( dllname, "ApplicationMgr" );
175}
176
177//------------------------------------------------------------------------------
179 //------------------------------------------------------------------------------
180 return createApplicationMgr( "GaudiCoreSvc", "ApplicationMgr" );
181}
182
183static std::list<IService*> s_bootServices;
184static SmartIF<IService> s_bootService;
185static SmartIF<IInterface> s_bootInterface;
186
188
189const std::list<IService*>& Gaudi::BootSvcLocator::getServices() const {
190 return s_appmgrInstance ? s_svclocInstance->getServices() : s_bootServices;
191}
192bool Gaudi::BootSvcLocator::existsService( std::string_view name ) const {
193 return s_appmgrInstance && s_svclocInstance->existsService( name );
194}
195
197 return s_appmgrInstance ? s_svclocInstance->service( typeName, createIf ) : s_bootService;
198}
199
200#ifdef GAUDI_HASCLASSVISIBILITY
201# pragma GCC visibility push( default )
202#endif
203// Python bootstrap helpers
204extern "C" {
205#define PyHelper( x ) py_bootstrap_##x
207IInterface* PyHelper( getService )( IInterface* app, char* name ) {
208 auto svcloc = SmartIF<ISvcLocator>( app );
209 return svcloc ? svcloc->service<IInterface>( std::string_view{ name } ).get() : nullptr;
210}
211bool PyHelper( setProperty )( IInterface* p, char* name, char* value ) {
212 auto prop = SmartIF<IProperty>( p );
213 return prop && prop->setProperty( name, value ).isSuccess();
214}
215const char* PyHelper( getProperty )( IInterface* p, char* name ) {
216 auto prop = SmartIF<IProperty>( p );
217 if ( !prop ) return nullptr;
218 // this is needed to guarantee that Python can access the returned char*
219 static std::string value;
220 value = prop->getProperty( name ).toString();
221 return value.c_str();
222}
223void PyHelper( setOption )( IInterface* app, char* key, char* value ) {
224 if ( auto svcloc = SmartIF<ISvcLocator>( app ) ) { svcloc->getOptsSvc().set( key, value ); }
225}
227 auto ui = SmartIF<IAppMgrUI>( app );
228 return ui && ui->configure().isSuccess();
229}
231
232bool py_bootstrap_app_run( IInterface* i, int maxevt ) {
233 auto ep = SmartIF<IEventProcessor>( i );
234 bool stat = false;
235 // Relinquish the GIL to allow python algs in MT mode
236 Py_BEGIN_ALLOW_THREADS;
237 stat = ep && ep->executeRun( maxevt ).isSuccess();
238 Py_END_ALLOW_THREADS;
239 return stat;
240}
241
242#define PyFSMHelper( s ) \
243 bool py_bootstrap_fsm_##s( IInterface* i ) { \
244 auto fsm = SmartIF<IStateful>( i ); \
245 return fsm && fsm->s().isSuccess(); \
246 }
247
248// clang-format off
249PyFSMHelper( configure )
250PyFSMHelper( initialize )
251PyFSMHelper( start )
252PyFSMHelper( stop )
253PyFSMHelper( finalize )
254PyFSMHelper( terminate )
255// clang-format on
256}
257#ifdef GAUDI_HASCLASSVISIBILITY
258# pragma GCC visibility pop
259#endif
const char *PyHelper getProperty(IInterface *p, char *name)
bool PyHelper configureApp(IInterface *app)
IInterface *PyHelper getService(IInterface *app, char *name)
bool py_bootstrap_app_run(IInterface *i, int maxevt)
IInterface *PyHelper createApplicationMgr()
#define PyFSMHelper(s)
void PyHelper setOption(IInterface *app, char *key, char *value)
bool PyHelper setProperty(IInterface *p, char *name, char *value)
#define PyHelper(x)
int PyHelper ROOT_VERSION_CODE()
SmartIF< IFace > make_SmartIF(IFace *iface)
Definition SmartIF.h:143
A dual-stage boostrap mechanism is used to ensure an orderly startup of the ApplicationMgr.
Definition Bootstrap.cpp:50
const std::list< IService * > & getServices() const override
SmartIF< IService > & service(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true) override
Returns a smart pointer to a service.
bool existsService(std::string_view name) const override
Helper class to parse a string of format "type/name".
Application Manager User Interface.
Definition IAppMgrUI.h:31
Definition of the basic interface.
Definition IInterface.h:225
virtual unsigned long release() const =0
Release Interface instance.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition ISvcLocator.h:42
Small smart pointer class with automatic reference counting for IInterface.
Definition SmartIF.h:28
TYPE * get() const
Get interface pointer.
Definition SmartIF.h:82
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition __init__.py:1
GAUDI_API ISvcLocator * svcLocator()
GAUDI_API IAppMgrUI * createApplicationMgr()
GAUDI_API IInterface * createInstance(const std::string &name, const std::string &factname, const std::string &ddlname)
GAUDI_API ISvcLocator * setInstance(ISvcLocator *newInstance)
Set new instance of service locator.
GAUDI_API IAppMgrUI * createApplicationMgrEx(const std::string &dllname, const std::string &factname)
get
decorate the vector of properties
Definition decorators.py:94
GAUDI_API unsigned long loadDynamicLib(const std::string &name, ImageHandle *handle)
Load dynamic link library.
Definition System.cpp:115
GAUDI_API const std::string getLastErrorString()
Get last system error as string.
Definition System.cpp:234