Gaudi Framework, version v20r2

Generated: 18 Jul 2008

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 }

Generated at Fri Jul 18 11:59:22 2008 for Gaudi Framework, version v20r2 by Doxygen version 1.5.1 written by Dimitri van Heesch, © 1997-2004