The Gaudi Framework  v33r1 (b1225454)
Bootstrap.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 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 
24 #include "GaudiKernel/Service.h"
25 #include <Gaudi/Algorithm.h>
26 
29 
30 #include "RVersion.h"
31 
32 namespace Gaudi {
33 
49  class BootSvcLocator : public implements<ISvcLocator> {
50  public:
51 #if !defined( GAUDI_V22_API ) || defined( G22_NEW_SVCLOCATOR )
53  IInterface*& pinterface ) override;
55  const bool createIf = true ) override;
56 #endif
57  const std::list<IService*>& getServices() const override;
58  bool existsService( std::string_view name ) const override;
59 
61  SmartIF<IService>& service( const Gaudi::Utils::TypeNameString& typeName, const bool createIf = true ) override;
62  };
63 } // namespace Gaudi
64 
65 static SmartIF<ISvcLocator> s_svclocInstance;
66 static SmartIF<IAppMgrUI> s_appmgrInstance;
67 
68 //------------------------------------------------------------------------------
69 IAppMgrUI* Gaudi::createApplicationMgr( const std::string& dllname, const std::string& factname )
70 //------------------------------------------------------------------------------
71 {
72  // Allow not for multiple AppManagers: If already instantiated then just
73  // return it
74  if ( !s_appmgrInstance ) {
75  s_appmgrInstance = createApplicationMgrEx( dllname, factname );
76  s_svclocInstance = s_appmgrInstance;
77  }
78  return s_appmgrInstance.get();
79 }
80 
81 //------------------------------------------------------------------------------
82 IAppMgrUI* Gaudi::createApplicationMgrEx( const std::string& dllname, const std::string& factname )
83 //------------------------------------------------------------------------------
84 {
85  // Create an instance of the application Manager
86  auto iif = make_SmartIF( Gaudi::createInstance( "ApplicationMgr", factname, dllname ) );
87  // Locate few interfaces of the Application Manager
88  return iif ? iif.as<IAppMgrUI>().get() : nullptr;
89 }
90 
91 //------------------------------------------------------------------------------
93 //------------------------------------------------------------------------------
94 //
95 // A dual-stage bootstrap mechanism is used to ensure an orderly startup
96 // of the ApplicationMgr. If this function is called before the singleton
97 // ApplicationMgr instance exists, a BootSvcLocator singleton instance is
98 // created. This responds to any subsequent requests for services by
99 // returning StatusCode::FAILURE, unless the ApplicationMgr singleton
100 // instance has been created in the interim. In this case, the BootSvcLocator
101 // forwards the request to the ApplicationMgr instance. The motivation for
102 // this is to handle static object instances where the constructor attempts
103 // to locate services and would otherwise instantiate the ApplicationMgr
104 // instance in an unorderly manner. This logic requires that the
105 // ApplicationMgr instance is created explicitly.
106 
107 {
108  if ( !s_svclocInstance ) {
109  IAppMgrUI* iappmgr = createApplicationMgr();
110  if ( iappmgr ) {
111  s_svclocInstance = iappmgr;
112  if ( s_svclocInstance ) return s_svclocInstance;
113  }
114  //---Reverted change to create a Minimal SvcLocator in case is requested before AppMgr is created
115  // if( 0 == s_appmgrInstance ) {
116  // s_svclocInstance = new BootSvcLocator();
117  //} else {
118  // StatusCode sc = s_appmgrInstance->queryInterface( ISvcLocator::interfaceID(),
119  // pp_cast<void>(&s_svclocInstance) );
120  // if( sc.isSuccess() ) {
121  // return s_svclocInstance;
122  // }
123  //}
124  }
125  return s_svclocInstance;
126 }
127 
128 //------------------------------------------------------------------------------
130 //------------------------------------------------------------------------------
131 {
132  ISvcLocator* oldInstance = s_svclocInstance.get();
133  s_svclocInstance = newInstance;
134  s_appmgrInstance = s_svclocInstance;
135  return oldInstance;
136 }
137 
138 //------------------------------------------------------------------------------
139 IAppMgrUI* Gaudi::setInstance( IAppMgrUI* newInstance )
140 //------------------------------------------------------------------------------
141 {
142  IAppMgrUI* oldInstance = s_appmgrInstance.get();
143  s_appmgrInstance = newInstance;
144  s_svclocInstance = s_appmgrInstance;
145  return oldInstance;
146 }
147 
148 //------------------------------------------------------------------------------
149 IInterface* Gaudi::createInstance( const std::string& name, const std::string& factname, const std::string& dllname )
150 //------------------------------------------------------------------------------
151 {
152 
153  IInterface* ii = ObjFactory::create( factname, nullptr ).release();
154  if ( ii ) return ii;
155  IService* is = Service::Factory::create( factname, name, nullptr ).release();
156  if ( is ) return is;
157  IAlgorithm* ia = Algorithm::Factory::create( factname, name, nullptr ).release();
158  if ( ia ) return ia;
159 
160  void* libHandle = nullptr;
161  if ( System::loadDynamicLib( dllname, &libHandle ) ) {
162  ii = ObjFactory::create( factname, nullptr ).release();
163  if ( ii ) return ii;
164  is = Service::Factory::create( factname, name, nullptr ).release();
165  if ( is ) return is;
166  ia = Algorithm::Factory::create( factname, name, nullptr ).release();
167  if ( ia ) return ia;
168  } else {
169  // DLL library not loaded. Try in the local module
171  std::cout << "Gaudi::Bootstrap: Not found DLL " << dllname << std::endl;
172  }
173  return nullptr;
174 }
175 
176 //------------------------------------------------------------------------------
178  //------------------------------------------------------------------------------
179  return createApplicationMgr( dllname, "ApplicationMgr" );
180 }
181 
182 //------------------------------------------------------------------------------
184  //------------------------------------------------------------------------------
185  return createApplicationMgr( "GaudiCoreSvc", "ApplicationMgr" );
186 }
187 
188 //=======================================================================
189 // BootSvcLocator
190 //=======================================================================
191 
192 static std::list<IService*> s_bootServices;
193 static SmartIF<IService> s_bootService;
194 static SmartIF<IInterface> s_bootInterface;
195 
197 
198 #if !defined( GAUDI_V22_API ) || defined( G22_NEW_SVCLOCATOR )
200  IInterface*& pinterface ) {
202  if ( s_appmgrInstance ) {
203  sc = s_svclocInstance->getService( typeName, iid, pinterface );
204  } else {
205  pinterface = s_bootInterface.get();
206  }
207  return sc;
208 }
210  const bool createIf ) {
212  if ( s_appmgrInstance ) {
213  sc = s_svclocInstance->getService( typeName, svc, createIf );
214  } else {
215  svc = s_bootService.get();
216  }
217  return sc;
218 }
219 #endif
220 
222  return s_appmgrInstance ? s_svclocInstance->getServices() : s_bootServices;
223 }
224 bool Gaudi::BootSvcLocator::existsService( std::string_view name ) const {
225  return s_appmgrInstance && s_svclocInstance->existsService( name );
226 }
227 
229  return s_appmgrInstance ? s_svclocInstance->service( typeName, createIf ) : s_bootService;
230 }
231 
232 #ifdef GAUDI_HASCLASSVISIBILITY
233 # pragma GCC visibility push( default )
234 #endif
235 // Python bootstrap helpers
236 extern "C" {
237 #define PyHelper( x ) py_bootstrap_##x
240  auto svcloc = SmartIF<ISvcLocator>( app );
241  return svcloc ? svcloc->service<IInterface>( std::string_view{name} ).get() : nullptr;
242 }
243 bool PyHelper( setProperty )( IInterface* p, char* name, char* value ) {
244  auto prop = SmartIF<IProperty>( p );
245  return prop && prop->setProperty( name, value ).isSuccess();
246 }
247 const char* PyHelper( getProperty )( IInterface* p, char* name ) {
248  auto prop = SmartIF<IProperty>( p );
249  return prop ? prop->getProperty( name ).toString().c_str() : nullptr;
250 }
252  auto ui = SmartIF<IAppMgrUI>( app );
253  return ui && ui->configure().isSuccess();
254 }
255 bool PyHelper( addPropertyToCatalogue )( IInterface* p, char* comp, char* name, char* value ) {
256  auto jos = SmartIF<IJobOptionsSvc>( p );
257  return jos && jos->addPropertyToCatalogue( comp, Gaudi::Property<std::string>( name, value ) ).isSuccess();
258 }
260 
261 #define PyFSMHelper( s ) \
262  bool py_bootstrap_fsm_##s( IInterface* i ) { \
263  auto fsm = SmartIF<IStateful>( i ); \
264  return fsm && fsm->s().isSuccess(); \
265  }
266 
267 PyFSMHelper( configure ) PyFSMHelper( initialize ) PyFSMHelper( start ) PyFSMHelper( stop ) PyFSMHelper( finalize )
268  PyFSMHelper( terminate )
269 
270  bool py_bootstrap_app_run( IInterface* i, int maxevt ) {
271  auto ep = SmartIF<IEventProcessor>( i );
272  return ep && ep->executeRun( maxevt ).isSuccess();
273 }
274 }
275 #ifdef GAUDI_HASCLASSVISIBILITY
276 # pragma GCC visibility pop
277 #endif
#define PyHelper(x)
Definition: Bootstrap.cpp:237
int PyHelper() ROOT_VERSION_CODE()
Definition: Bootstrap.cpp:259
#define PyFSMHelper(s)
Definition: Bootstrap.cpp:261
Base class used to implement the interfaces.
Definition: implements.h:19
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:35
const std::list< IService * > & getServices() const override
Definition: Bootstrap.cpp:221
Implementation of property with value of concrete type.
Definition: Property.h:370
bool existsService(std::string_view name) const override
Definition: Bootstrap.cpp:224
T endl(T... args)
bool PyHelper() addPropertyToCatalogue(IInterface *p, char *comp, char *name, char *value)
Definition: Bootstrap.cpp:255
GAUDI_API IAppMgrUI * createApplicationMgrEx(const std::string &dllname, const std::string &factname)
auto get(const Handle &handle, const Algo &, const EventContext &) -> decltype(details::deref(handle.get()))
const char *PyHelper() getProperty(IInterface *p, char *name)
Definition: Bootstrap.cpp:247
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:86
def start
Definition: IOTest.py:108
STL class.
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:86
Interface ID class.
Definition: IInterface.h:39
Helper class to parse a string of format "type/name".
GAUDI_API ISvcLocator * svcLocator()
SmartIF< IService > & service(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true) override
Returns a smart pointer to a service.
Definition: Bootstrap.cpp:228
General service interface definition.
Definition: IService.h:28
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:61
Definition of the basic interface.
Definition: IInterface.h:254
virtual StatusCode getService(const Gaudi::Utils::TypeNameString &typeName, IService *&svc, const bool createIf=true)
Get a reference to the service given a service name.
Definition: ISvcLocator.h:45
bool PyHelper() setProperty(IInterface *p, char *name, char *value)
Definition: Bootstrap.cpp:243
The IAlgorithm is the interface implemented by the Algorithm base class.
Definition: IAlgorithm.h:38
Application Manager User Interface.
Definition: IAppMgrUI.h:30
GAUDI_API ISvcLocator * setInstance(ISvcLocator *newInstance)
Set new instance of service locator.
virtual unsigned long release()=0
Release Interface instance.
virtual bool existsService(std::string_view name) const =0
Check the existence of a service given a service name.
StatusCode getService(const Gaudi::Utils::TypeNameString &typeName, const InterfaceID &iid, IInterface *&pinterface) override
Definition: Bootstrap.cpp:199
A dual-stage boostrap mechanism is used to ensure an orderly startup of the ApplicationMgr.
Definition: Bootstrap.cpp:49
constexpr static const auto FAILURE
Definition: StatusCode.h:101
SmartIF< IFace > make_SmartIF(IFace *iface)
Definition: SmartIF.h:150
virtual const std::list< IService * > & getServices() const =0
Get a reference to a service and create it if it does not exists.
GAUDI_API const std::string getLastErrorString()
Get last system error as string.
Definition: System.cpp:272
int maxevt
Definition: Bootstrap.cpp:270
std::string typeName(const std::type_info &typ)
Definition: Dictionary.cpp:31
bool PyHelper() configureApp(IInterface *app)
Definition: Bootstrap.cpp:251
IInterface *PyHelper() getService(IInterface *app, char *name)
Definition: Bootstrap.cpp:239
Header file for std:chrono::duration-based Counters.
Definition: __init__.py:1
GAUDI_API IInterface * createInstance(const std::string &name, const std::string &factname, const std::string &ddlname)
GAUDI_API IAppMgrUI * createApplicationMgr(const std::string &dllname, const std::string &factname)
GAUDI_API unsigned long loadDynamicLib(const std::string &name, ImageHandle *handle)
Load dynamic link library.
Definition: System.cpp:145