HandleRoot.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <common/common.hpp>
  14. #include <NdbMutex.h>
  15. #include <common/DiagArea.hpp>
  16. #include "HandleRoot.hpp"
  17. #include "HandleEnv.hpp"
  18. #include "HandleDbc.hpp"
  19. #include "HandleStmt.hpp"
  20. #include "HandleDesc.hpp"
  21. #include "PoolNdb.hpp"
  22. HandleRoot::HandleRoot() :
  23.     m_attrArea(m_attrSpec)
  24. {
  25.     m_attrArea.setHandle(this);
  26.     m_poolNdb = new PoolNdb();
  27. }
  28. HandleRoot::~HandleRoot()
  29. {
  30. }
  31. #ifdef NDB_WIN32
  32. static NdbMutex & root_mutex = * NdbMutex_Create();
  33. #else
  34. static NdbMutex root_mutex = NDB_MUTEX_INITIALIZER;
  35. #endif
  36. HandleRoot*
  37. HandleRoot::instance()
  38. {
  39.     NdbMutex_Lock(&root_mutex);
  40.     if (m_instance == 0)
  41. m_instance = new HandleRoot();
  42.     NdbMutex_Unlock(&root_mutex);
  43.     return m_instance;
  44. }
  45. void
  46. HandleRoot::lockHandle()
  47. {
  48.     NdbMutex_Lock(&root_mutex);
  49. }
  50. void
  51. HandleRoot::unlockHandle()
  52. {
  53.     NdbMutex_Unlock(&root_mutex);
  54. }
  55. // check and find handle types and handles
  56. SQLSMALLINT
  57. HandleRoot::findParentType(SQLSMALLINT childType)
  58. {
  59.     switch (childType) {
  60.     case SQL_HANDLE_ENV:
  61. return SQL_HANDLE_ROOT;
  62.     case SQL_HANDLE_DBC:
  63. return SQL_HANDLE_ENV;
  64.     case SQL_HANDLE_STMT:
  65. return SQL_HANDLE_DBC;
  66.     case SQL_HANDLE_DESC:
  67. return SQL_HANDLE_DBC;
  68.     }
  69.     return -1;
  70. }
  71. HandleBase*
  72. HandleRoot::findBase(SQLSMALLINT handleType, void* pHandle)
  73. {
  74.     switch (handleType) {
  75.     case SQL_HANDLE_ROOT:
  76. return getRoot();
  77.     case SQL_HANDLE_ENV:
  78. return findEnv(pHandle);
  79.     case SQL_HANDLE_DBC:
  80. return findDbc(pHandle);
  81.     case SQL_HANDLE_STMT:
  82. return findStmt(pHandle);
  83.     case SQL_HANDLE_DESC:
  84. return findDesc(pHandle);
  85.     }
  86.     return 0;
  87. }
  88. HandleEnv*
  89. HandleRoot::findEnv(void* pHandle)
  90. {
  91.     lockHandle();
  92.     ValidList::iterator i = m_validList.find(pHandle);
  93.     if (i == m_validList.end() || (*i).second != SQL_HANDLE_ENV) {
  94. unlockHandle();
  95. return 0;
  96.     }
  97.     unlockHandle();
  98.     ctx_assert(pHandle != 0);
  99.     return static_cast<HandleEnv*>(pHandle);
  100. }
  101. HandleDbc*
  102. HandleRoot::findDbc(void* pHandle)
  103. {
  104.     lockHandle();
  105.     ValidList::iterator i = m_validList.find(pHandle);
  106.     if (i == m_validList.end() || (*i).second != SQL_HANDLE_DBC) {
  107. unlockHandle();
  108. return 0;
  109.     }
  110.     unlockHandle();
  111.     ctx_assert(pHandle != 0);
  112.     return static_cast<HandleDbc*>(pHandle);
  113. }
  114. HandleStmt*
  115. HandleRoot::findStmt(void* pHandle)
  116. {
  117.     lockHandle();
  118.     ValidList::iterator i = m_validList.find(pHandle);
  119.     if (i == m_validList.end() || (*i).second != SQL_HANDLE_STMT) {
  120. unlockHandle();
  121. return 0;
  122.     }
  123.     unlockHandle();
  124.     ctx_assert(pHandle != 0);
  125.     return static_cast<HandleStmt*>(pHandle);
  126. }
  127. HandleDesc*
  128. HandleRoot::findDesc(void* pHandle)
  129. {
  130.     lockHandle();
  131.     ValidList::iterator i = m_validList.find(pHandle);
  132.     if (i == m_validList.end() || (*i).second != SQL_HANDLE_DESC) {
  133. unlockHandle();
  134. return 0;
  135.     }
  136.     unlockHandle();
  137.     ctx_assert(pHandle != 0);
  138.     return static_cast<HandleDesc*>(pHandle);
  139. }
  140. // add or remove handle from validation list
  141. void
  142. HandleRoot::record(SQLSMALLINT handleType, HandleBase* pHandle, bool add)
  143. {
  144.     switch (handleType) {
  145.     case SQL_HANDLE_ENV:
  146.     case SQL_HANDLE_DBC:
  147.     case SQL_HANDLE_STMT:
  148.     case SQL_HANDLE_DESC:
  149. break;
  150.     default:
  151. ctx_assert(false);
  152. break;
  153.     }
  154.     ctx_assert(pHandle != 0);
  155.     lockHandle();
  156.     ValidList::iterator i = m_validList.find(pHandle);
  157.     if (add) {
  158. if (i != m_validList.end()) {
  159.     unlockHandle();
  160.     ctx_assert(false);
  161. }
  162. m_validList.insert(ValidList::value_type(pHandle, handleType));
  163.     } else {
  164. if (i == m_validList.end() || (*i).second != handleType) {
  165.     unlockHandle();
  166.     ctx_assert(false);
  167. }
  168. m_validList.erase(i);
  169.     }
  170.     unlockHandle();
  171. }
  172. // allocate and free handles
  173. void
  174. HandleRoot::sqlAllocEnv(Ctx& ctx, HandleEnv** ppEnv)
  175. {
  176.     if (ppEnv == 0) {
  177. ctx.pushStatus(Sqlstate::_HY009, Error::Gen, "cannot allocate environment handle - null return address");
  178. return;
  179.     }
  180.     HandleEnv* pEnv = new HandleEnv(this);
  181.     pEnv->ctor(ctx);
  182.     if (! ctx.ok()) {
  183. pEnv->dtor(ctx);
  184. delete pEnv;
  185. return;
  186.     }
  187.     lockHandle();
  188.     m_listEnv.push_back(pEnv);
  189.     unlockHandle();
  190.     getRoot()->record(SQL_HANDLE_ENV, pEnv, true);
  191.     *ppEnv = pEnv;
  192. }
  193. void
  194. HandleRoot::sqlAllocHandle(Ctx& ctx, SQLSMALLINT childType, HandleBase** ppChild)
  195. {
  196.     switch (childType) {
  197.     case SQL_HANDLE_ENV:
  198. sqlAllocEnv(ctx, (HandleEnv**)ppChild);
  199. return;
  200.     }
  201.     ctx.pushStatus(Sqlstate::_HY092, Error::Gen, "invalid child handle type %d", (int)childType);
  202. }
  203. void
  204. HandleRoot::sqlFreeEnv(Ctx& ctx, HandleEnv* pEnv)
  205. {
  206.     pEnv->dtor(ctx);
  207.     if (! ctx.ok()) {
  208. return;
  209.     }
  210.     lockHandle();
  211.     m_listEnv.remove(pEnv);
  212.     unlockHandle();
  213.     getRoot()->record(SQL_HANDLE_ENV, pEnv, false);
  214.     delete pEnv;
  215. }
  216. void
  217. HandleRoot::sqlFreeHandle(Ctx& ctx, SQLSMALLINT childType, HandleBase* pChild)
  218. {
  219.     switch (childType) {
  220.     case SQL_HANDLE_ENV:
  221. sqlFreeEnv(ctx, (HandleEnv*)pChild);
  222. return;
  223.     }
  224.     ctx.pushStatus(Sqlstate::_HY092, Error::Gen, "invalid child handle type %d", (int)childType);
  225. }
  226. // process-level attributes
  227. void
  228. HandleRoot::sqlSetRootAttr(Ctx& ctx, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER stringLength)
  229. {
  230.     lockHandle();
  231.     baseSetHandleAttr(ctx, m_attrArea, attribute, value, stringLength);
  232.     unlockHandle();
  233. }
  234. void
  235. HandleRoot::sqlGetRootAttr(Ctx& ctx, SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER bufferLength, SQLINTEGER* stringLength)
  236. {
  237.     lockHandle();
  238.     baseGetHandleAttr(ctx, m_attrArea, attribute, value, bufferLength, stringLength);
  239.     unlockHandle();
  240. }
  241. // the instance
  242. HandleRoot* HandleRoot::m_instance = 0;