driver_mgr.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:8k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: driver_mgr.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:19:01  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.15
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: driver_mgr.cpp,v 1000.2 2004/06/01 19:19:01 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Author:  Vladimir Soussov
  35.  *
  36.  * File Description:  Driver manager
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <dbapi/driver/driver_mgr.hpp>
  41. #include <corelib/ncbidll.hpp>
  42. BEGIN_NCBI_SCOPE
  43. class C_xDriverMgr : public I_DriverMgr
  44. {
  45. public:
  46.     C_xDriverMgr(unsigned int nof_drivers= 16) {
  47.         m_NofRoom= nof_drivers? nof_drivers : 16;
  48.         m_Drivers= new SDrivers[m_NofRoom];
  49.         m_NofDrvs= 0;
  50.     }
  51.     
  52.     FDBAPI_CreateContext GetDriver(const string& driver_name, 
  53.                                    string* err_msg= 0);
  54.     
  55.     virtual void RegisterDriver(const string&        driver_name,
  56.                                 FDBAPI_CreateContext driver_ctx_func);
  57.     virtual ~C_xDriverMgr() {
  58.         delete [] m_Drivers;
  59.     }
  60.     
  61. protected:
  62.     bool LoadDriverDll(const string& driver_name, string* err_msg);
  63.     
  64. private:
  65.     typedef void            (*FDriverRegister) (I_DriverMgr& mgr);
  66.     typedef FDriverRegister (*FDllEntryPoint)  (void);
  67.     struct SDrivers {
  68.         string               drv_name;
  69.         FDBAPI_CreateContext drv_func;
  70.     } *m_Drivers;
  71.     unsigned int m_NofDrvs;
  72.     unsigned int m_NofRoom;
  73.     CFastMutex m_Mutex1;
  74.     CFastMutex m_Mutex2;
  75. };
  76. void C_xDriverMgr::RegisterDriver(const string&        driver_name,
  77.                                   FDBAPI_CreateContext driver_ctx_func)
  78. {
  79.     if(m_NofDrvs < m_NofRoom) {
  80.         CFastMutexGuard mg(m_Mutex2);
  81.         for(unsigned int i= m_NofDrvs; i--; ) {
  82.             if(m_Drivers[i].drv_name == driver_name) {
  83.                 m_Drivers[i].drv_func= driver_ctx_func;
  84.                 return;
  85.             }
  86.         }
  87.         m_Drivers[m_NofDrvs++].drv_func= driver_ctx_func;
  88.         m_Drivers[m_NofDrvs-1].drv_name= driver_name;
  89.     }
  90.     else {
  91.         throw CDB_ClientEx(eDB_Error, 101, "C_xDriverMgr::RegisterDriver",
  92.                            "No space left for driver registration");
  93.     }
  94. }
  95. FDBAPI_CreateContext C_xDriverMgr::GetDriver(const string& driver_name,
  96.                                              string* err_msg)
  97. {
  98.     CFastMutexGuard mg(m_Mutex1);
  99.     unsigned int i;
  100.     
  101.     for(i= m_NofDrvs; i--; ) {
  102.         if(m_Drivers[i].drv_name == driver_name) {
  103.             return m_Drivers[i].drv_func;
  104.         }
  105.     }
  106.     
  107.     if (!LoadDriverDll(driver_name, err_msg)) {
  108.         return 0;
  109.     }
  110.     for(i= m_NofDrvs; i--; ) {
  111.         if(m_Drivers[i].drv_name == driver_name) {
  112.             return m_Drivers[i].drv_func;
  113.         }
  114.     }
  115.     throw CDB_ClientEx(eDB_Error, 200, "C_DriverMgr::GetDriver",
  116.                        "internal error");
  117. }
  118. bool C_xDriverMgr::LoadDriverDll(const string& driver_name, string* err_msg)
  119. {
  120.     try {
  121.         CDll drv_dll("dbapi_driver_" + driver_name);
  122.         FDllEntryPoint entry_point;
  123.         if ( !drv_dll.GetEntryPoint_Func("DBAPI_E_" + driver_name,
  124.                                          &entry_point) ) {
  125.             drv_dll.Unload();
  126.             return false;
  127.         }
  128.         FDriverRegister reg = entry_point();
  129.         if(!reg) {
  130.             throw CDB_ClientEx(eDB_Fatal, 300, "C_DriverMgr::LoadDriverDll",
  131.                                "driver reports an unrecoverable error "
  132.                                "(e.g. conflict in libraries)");
  133.         }
  134.         reg(*this);
  135.         return true;
  136.     }
  137.     catch (exception& e) {
  138.         if(err_msg) *err_msg= e.what();
  139.         return false;
  140.     }
  141. }
  142. static C_xDriverMgr* s_DrvMgr= 0;
  143. static int           s_DrvCount= 0;
  144. DEFINE_STATIC_FAST_MUTEX(s_DrvMutex);
  145. C_DriverMgr::C_DriverMgr(unsigned int nof_drivers)
  146. {
  147.     CFastMutexGuard mg(s_DrvMutex); // lock the mutex
  148.     if(!s_DrvMgr) { // There is no driver manager yet
  149.         s_DrvMgr= new C_xDriverMgr(nof_drivers);
  150.     }
  151.     ++s_DrvCount;
  152. }
  153.     
  154. C_DriverMgr::~C_DriverMgr()
  155. {
  156.     CFastMutexGuard mg(s_DrvMutex); // lock the mutex
  157.     if(--s_DrvCount <= 0) { // this is a last one
  158.         delete s_DrvMgr;
  159.         s_DrvMgr= 0;
  160.         s_DrvCount= 0;
  161.     }
  162. }
  163. FDBAPI_CreateContext C_DriverMgr::GetDriver(const string& driver_name,
  164.                                             string* err_msg)
  165. {
  166.     return s_DrvMgr->GetDriver(driver_name, err_msg);
  167. }
  168. void C_DriverMgr::RegisterDriver(const string&        driver_name,
  169.                                  FDBAPI_CreateContext driver_ctx_func)
  170. {
  171.     s_DrvMgr->RegisterDriver(driver_name, driver_ctx_func);
  172. }
  173. I_DriverContext* C_DriverMgr::GetDriverContext(const string&       driver_name,
  174.                                                string*             err_msg,
  175.                                                map<string,string>* attr)
  176. {
  177.     FDBAPI_CreateContext create_context_func= GetDriver(driver_name, err_msg);
  178.     if(!create_context_func) 
  179.         return 0;
  180.         
  181.     return create_context_func(attr);
  182. }
  183. END_NCBI_SCOPE
  184. /*
  185.  * ===========================================================================
  186.  * $Log: driver_mgr.cpp,v $
  187.  * Revision 1000.2  2004/06/01 19:19:01  gouriano
  188.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.15
  189.  *
  190.  * Revision 1.15  2004/05/17 21:11:38  gorelenk
  191.  * Added include of PCH ncbi_pch.hpp
  192.  *
  193.  * Revision 1.14  2003/11/19 15:33:55  ucko
  194.  * Adjust for CDll API change.
  195.  *
  196.  * Revision 1.13  2002/09/19 20:05:43  vasilche
  197.  * Safe initialization of static mutexes
  198.  *
  199.  * Revision 1.12  2002/09/19 18:47:31  soussov
  200.  * LoadDriverDll now allows driver to report an unrecoverable error through NULL return from entry_point function
  201.  *
  202.  * Revision 1.11  2002/04/23 16:46:17  soussov
  203.  * GetDriverContext added
  204.  *
  205.  * Revision 1.10  2002/04/12 18:48:30  soussov
  206.  * makes driver_mgr working properly in mt environment
  207.  *
  208.  * Revision 1.9  2002/04/09 22:18:15  vakatov
  209.  * Moved code from the header
  210.  *
  211.  * Revision 1.8  2002/04/04 23:59:37  soussov
  212.  * bug in RegisterDriver fixed
  213.  *
  214.  * Revision 1.7  2002/04/04 23:57:39  soussov
  215.  * return of error message from dlopen added
  216.  *
  217.  * Revision 1.6  2002/02/14 00:59:42  vakatov
  218.  * Clean-up: warning elimination, fool-proofing, fine-tuning, identation, etc.
  219.  *
  220.  * Revision 1.5  2002/01/23 21:29:48  soussov
  221.  * replaces map with array
  222.  *
  223.  * Revision 1.4  2002/01/20 07:26:58  vakatov
  224.  * Fool-proofed to compile func_ptr/void_ptr type casts on all compilers.
  225.  * Added virtual destructor.
  226.  * Temporarily get rid of the MT-safety features -- they need to be
  227.  * implemented here more carefully (in the nearest future).
  228.  *
  229.  * Revision 1.3  2002/01/20 05:24:42  vakatov
  230.  * identation
  231.  *
  232.  * Revision 1.2  2002/01/17 23:19:13  soussov
  233.  * makes gcc happy
  234.  *
  235.  * Revision 1.1  2002/01/17 22:17:25  soussov
  236.  * adds driver manager
  237.  *
  238.  * ===========================================================================
  239.  */