| # Gaudi Framework, version v20r2
Generated: 18 Jul 2008

- Main Page
- Namespaces
- Classes
- Files
- Directories
- Related Pages

- Search for |

- File List
- File Members

# Bootstrap.cpp

Go to the documentation of this file.

    00001 //$Id: Bootstrap.cpp,v 1.14 2007/12/12 16:02:32 marcocle Exp $
    00002
    00003 #include <iostream>
    00004
    00005 #include "GaudiKernel/Bootstrap.h"
    00006 #include "GaudiKernel/System.h"
    00007
    00008 #include "GaudiKernel/IInterface.h"
    00009 #include "GaudiKernel/IAlgorithm.h"
    00010 #include "GaudiKernel/IService.h"
    00011 #include "GaudiKernel/IAppMgrUI.h"
    00012 #include "GaudiKernel/ISvcLocator.h"
    00013 #include "GaudiKernel/IClassManager.h"
    00014
    00015 #include "Reflex/PluginService.h"
    00016 using ROOT::Reflex::PluginService;
    00017
    00018
    00019 namespace Gaudi
    00020 {
    00021
    00037   class BootSvcLocator : virtual public ISvcLocator {
    00038   public:
    00039     BootSvcLocator();
    00040     virtual ~BootSvcLocator();
    00042     virtual unsigned long addRef();
    00044     virtual unsigned long release();
    00046     virtual StatusCode queryInterface(const InterfaceID& iid, void** pinterface);
    00047     virtual StatusCode getService( const std::string& name,
    00048                                    IService*&  svc );
    00049     virtual StatusCode getService( const std::string& name,
    00050                                    const InterfaceID& iid,
    00051                                    IInterface*& pinterface );
    00052     virtual StatusCode getService( const std::string& name,
    00053                                    IService*& svc,
    00054                                    bool createIf );
    00055     virtual const std::list<IService*>& getServices( ) const;
    00056     virtual bool existsService( const std::string& name ) const;
    00057   private:
    00058     unsigned long m_refcount;
    00059   };
    00060 }
    00061
    00062
    00063 static ISvcLocator* s_svclocInstance = 0;
    00064 static IAppMgrUI*   s_appmgrInstance = 0;
    00065
    00066 //------------------------------------------------------------------------------
    00067 IAppMgrUI* Gaudi::createApplicationMgr(const std::string& dllname,
    00068                                        const std::string& factname)
    00069 //------------------------------------------------------------------------------
    00070 {
    00071   // Allow not for multiple AppManagers: If already instantiated then just
    00072   // return it
    00073   if ( 0 == s_appmgrInstance )    {
    00074     s_appmgrInstance = createApplicationMgrEx(dllname, factname);
    00075     StatusCode sc = s_appmgrInstance->queryInterface( IID_ISvcLocator,
    00076                                                       pp_cast<void>(&s_svclocInstance) );
    00077   }
    00078   return s_appmgrInstance;
    00079 }
    00080
    00081 //------------------------------------------------------------------------------
    00082 IAppMgrUI* Gaudi::createApplicationMgrEx(const std::string& dllname,
    00083                                          const std::string& factname)
    00084 //------------------------------------------------------------------------------
    00085 {
    00086   StatusCode     status;
    00087   IInterface*    iif;
    00088   IAppMgrUI*     iappmgr;
    00089
    00090   // Create an instance of the application Manager
    00091   iif = Gaudi::createInstance( "ApplicationMgr", factname, dllname );
    00092   if( iif == 0 ) {
    00093     return 0;
    00094   }
    00095   // Locate few interfaces of the Application Manager
    00096   status = iif->queryInterface( IID_IAppMgrUI, pp_cast<void>(&iappmgr) );
    00097   if( status.isFailure() ) {
    00098     return 0;
    00099   }
    00100   iif->release();
    00101   return iappmgr;
    00102 }
    00103
    00104 //------------------------------------------------------------------------------
    00105 ISvcLocator* Gaudi::svcLocator()
    00106 //------------------------------------------------------------------------------
    00107 //
    00108 // A dual-stage boostrap mechanism is used to ensure an orderly startup
    00109 // of the ApplicationMgr. If this function is called before the singleton
    00110 // ApplicationMgr instance exists, a BootSvcLocator singleton instance is
    00111 // created. This responds to any subsequent requests for services by
    00112 // returning StatusCode::FAILURE, unless the ApplicationMgr singleton
    00113 // instance has been created in the interim. In this case, the BootSvcLocator
    00114 // forwards the request to the ApplicationMgr instance. The motiviation for
    00115 // this is to handle static object instances where the constructor attempts
    00116 // to locate services and would otherwise instantiate the ApplicationMgr
    00117 // instance in an unorderly manner. This logic requires that the
    00118 // ApplicationMgr instance is created explicitly.
    00119
    00120 {
    00121   if( 0 == s_svclocInstance )   {
    00122     IAppMgrUI* iappmgr = createApplicationMgr();
    00123     if( iappmgr ) {
    00124       StatusCode sc = iappmgr->queryInterface( IID_ISvcLocator,
    00125                                                pp_cast<void>(&s_svclocInstance) );
    00126       if( sc.isSuccess() ) {
    00127         return s_svclocInstance;
    00128       }
    00129     }
    00130     //---Reverted change to create a Minimal SvcLocator in case is requested before AppMgr is created
    00131     //if( 0 == s_appmgrInstance ) {
    00132     //  s_svclocInstance = new BootSvcLocator();
    00133     //} else {
    00134     //  StatusCode sc = s_appmgrInstance->queryInterface( IID_ISvcLocator,
    00135     //                                                  pp_cast<void>(&s_svclocInstance) );
    00136     //  if( sc.isSuccess() ) {
    00137     //    return s_svclocInstance;
    00138     //  }
    00139     //}
    00140   }
    00141   return s_svclocInstance;
    00142 }
    00143
    00144 //------------------------------------------------------------------------------
    00145 ISvcLocator* Gaudi::setInstance(ISvcLocator* newInstance)
    00146 //------------------------------------------------------------------------------
    00147 {
    00148   ISvcLocator* oldInstance = s_svclocInstance;
    00149   s_svclocInstance = newInstance;
    00150   if ( s_appmgrInstance )     {
    00151     s_appmgrInstance->release();
    00152     s_appmgrInstance = 0;
    00153   }
    00154   if ( s_svclocInstance )    {
    00155     s_svclocInstance->queryInterface (IID_IAppMgrUI, pp_cast<void>(&s_appmgrInstance));
    00156   }
    00157   return oldInstance;
    00158 }
    00159
    00160 //------------------------------------------------------------------------------
    00161 IAppMgrUI* Gaudi::setInstance(IAppMgrUI* newInstance)
    00162 //------------------------------------------------------------------------------
    00163 {
    00164   IAppMgrUI* oldInstance = s_appmgrInstance;
    00165   s_appmgrInstance = newInstance;
    00166   if ( s_svclocInstance )     {
    00167     s_svclocInstance->release();
    00168     s_svclocInstance = 0;
    00169   }
    00170   if ( s_appmgrInstance )    {
    00171     s_appmgrInstance->queryInterface (IID_ISvcLocator,
    00172                                       pp_cast<void>(&s_svclocInstance));
    00173   }
    00174   return oldInstance;
    00175 }
    00176
    00177 //------------------------------------------------------------------------------
    00178 IInterface* Gaudi::createInstance( const std::string& name,
    00179                                                 const std::string& factname,
    00180                                                 const std::string& dllname)
    00181 //------------------------------------------------------------------------------
    00182 {
    00183
    00184   IInterface* ii = PluginService::Create<IInterface*>(factname,(IInterface*)0);
    00185   if ( ii ) return ii;
    00186   IService* is = PluginService::Create<IService*>(factname, name, (ISvcLocator*)0);
    00187   if ( is ) return is;
    00188   IAlgorithm* ia = PluginService::Create<IAlgorithm*>(factname, name, (ISvcLocator*)0);
    00189   if ( ia ) return ia;
    00190
    00191   StatusCode status;
    00192   void* libHandle = 0;
    00193   status = System::loadDynamicLib( dllname, &libHandle);
    00194   if ( status.isSuccess() )   {
    00195     IInterface* ii = PluginService::Create<IInterface*>(factname, (IInterface*)0);
    00196     if ( ii ) return ii;
    00197     IService* is = PluginService::Create<IService*>(factname, name, (ISvcLocator*)0);
    00198     if ( is ) return is;
    00199     IAlgorithm* ia = PluginService::Create<IAlgorithm*>(factname, name, (ISvcLocator*)0);
    00200     if ( ia ) return ia;
    00201
    00202     return 0;
    00203   }
    00204   else {
    00205     // DLL library not loaded. Try in the local module
    00206     std::cout << System::getLastErrorString() << std::endl;
    00207     std::cout << "Gaudi::Bootstrap: Not found DLL " << dllname << std::endl;
    00208     return 0;
    00209   }
    00210 }
    00211
    00212 namespace {
    00213   class ShadowEntry    {
    00214   public:
    00215     std::string dllName;
    00216     std::string facName;
    00217     IFactory*   fac;
    00218   public:
    00219     ShadowEntry() {
    00220     }
    00221     ShadowEntry(const std::string& d, const std::string& n, const IFactory* f) {
    00222       dllName = d;
    00223       facName = n;
    00224       fac     = const_cast<IFactory*>(f);
    00225     }
    00226     ShadowEntry(const ShadowEntry& copy)   {
    00227       dllName = copy.dllName;
    00228       facName = copy.facName;
    00229       fac     = copy.fac;
    00230     }
    00231     ShadowEntry& operator=(const ShadowEntry& copy)   {
    00232       dllName = copy.dllName;
    00233       facName = copy.facName;
    00234       fac     = copy.fac;
    00235       return *this;
    00236     }
    00237   };
    00238 }
    00239
    00240 //------------------------------------------------------------------------------
    00241 IAppMgrUI* Gaudi::createApplicationMgr(const std::string& dllname )    {
    00242 //------------------------------------------------------------------------------
    00243   return createApplicationMgr(dllname, "ApplicationMgr");
    00244 }
    00245
    00246 //------------------------------------------------------------------------------
    00247 IAppMgrUI* Gaudi::createApplicationMgr()    {
    00248 //------------------------------------------------------------------------------
    00249   return createApplicationMgr("GaudiSvc", "ApplicationMgr");
    00250 }
    00251
    00252 //=======================================================================
    00253 // BootSvcLocator
    00254 //=======================================================================
    00255
    00256 static std::list<IService*> s_bootServices;
    00257 static IService*            s_bootService   = 0;
    00258 static IInterface*          s_bootInterface = 0;
    00259
    00260 using Gaudi::BootSvcLocator;
    00261
    00262 BootSvcLocator::BootSvcLocator() {
    00263   m_refcount = 0;
    00264 }
    00265 BootSvcLocator::~BootSvcLocator() {
    00266 }
    00267 unsigned long BootSvcLocator::addRef() {
    00268   m_refcount++;
    00269   return m_refcount;
    00270 }
    00271 unsigned long BootSvcLocator::release() {
    00272   unsigned long count = --m_refcount;
    00273   if( count <= 0) {
    00274     delete this;
    00275   }
    00276   return count;
    00277 }
    00278 StatusCode Gaudi::BootSvcLocator::queryInterface(const InterfaceID& iid, void** pinterface)
    00279 {
    00280   if( iid == IID_IInterface ) {
    00281     *pinterface = (IInterface*)this;
    00282     addRef();
    00283     return StatusCode::SUCCESS;
    00284   }
    00285   else if ( iid == IID_ISvcLocator ) {
    00286     *pinterface = (ISvcLocator*)this;
    00287     addRef();
    00288     return StatusCode::SUCCESS;
    00289   }
    00290   return StatusCode::FAILURE;
    00291 }
    00292 StatusCode Gaudi::BootSvcLocator::getService( const std::string& name,
    00293                                        IService*&  svc ) {
    00294   StatusCode sc = StatusCode::FAILURE;
    00295   if ( 0 != s_appmgrInstance ) {
    00296     sc = s_svclocInstance->getService(name, svc );
    00297   } else {
    00298     svc = s_bootService;
    00299   }
    00300   return sc;
    00301 }
    00302 StatusCode Gaudi::BootSvcLocator::getService( const std::string& name,
    00303                                        const InterfaceID& iid,
    00304                                        IInterface*& pinterface ) {
    00305   StatusCode sc = StatusCode::FAILURE;
    00306   if ( 0 != s_appmgrInstance ) {
    00307     sc = s_svclocInstance->getService(name, iid, pinterface );
    00308   } else {
    00309     pinterface = s_bootInterface;
    00310   }
    00311   return sc;
    00312 }
    00313 StatusCode Gaudi::BootSvcLocator::getService( const std::string& name,
    00314                                        IService*& svc,
    00315                                        bool createIf ) {
    00316   StatusCode sc = StatusCode::FAILURE;
    00317   if ( 0 != s_appmgrInstance ) {
    00318     sc = s_svclocInstance->getService(name, svc, createIf );
    00319   } else {
    00320     svc = s_bootService;
    00321   }
    00322   return sc;
    00323 }
    00324 const std::list<IService*>& Gaudi::BootSvcLocator::getServices( ) const {
    00325   StatusCode sc = StatusCode::FAILURE;
    00326   if ( 0 != s_appmgrInstance ) {
    00327     return s_svclocInstance->getServices( );
    00328   } else {
    00329     return s_bootServices;
    00330   }
    00331 }
    00332 bool Gaudi::BootSvcLocator::existsService( const std::string& name ) const {
    00333   bool result = false;
    00334   if ( 0 != s_appmgrInstance ) {
    00335     result = s_svclocInstance->existsService(name );
    00336   }
    00337   return result;
    00338 }