Mutex.hpp
上传用户: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. #ifndef BLOCK_MUTEX_HPP
  14. #define BLOCK_MUTEX_HPP
  15. #include "Callback.hpp"
  16. #include "SimulatedBlock.hpp"
  17. class Mutex;
  18. /**
  19.  * MutexHandle - A "reference" to a mutex
  20.  *             - Should be used together with Mutex
  21.  */
  22. class MutexHandle {
  23.   friend class Mutex;
  24. public:
  25.   MutexHandle(Uint32 id);
  26.   
  27.   bool isNull() const;
  28.   void release(SimulatedBlock::MutexManager & mgr);
  29. private:
  30.   const Uint32 m_mutexId;
  31.   Uint32 m_activeMutexPtrI;
  32. };
  33. /**
  34.  * MutexHandle2 - A template-based "reference" to a mutex
  35.  */
  36. template<Uint32 MutexId>
  37. class MutexHandle2 {
  38.   friend class Mutex;
  39. public:
  40.   MutexHandle2();
  41.   
  42.   bool isNull() const;
  43.   void release(SimulatedBlock::MutexManager & mgr);
  44. private:
  45.   Uint32 m_activeMutexPtrI;
  46. };
  47. /**
  48.  * A mutex - Used together with a MutexHandle to be put on the stack
  49.  */
  50. class Mutex {
  51. public:
  52.   Mutex(Signal*, SimulatedBlock::MutexManager & mgr, MutexHandle &);
  53.   
  54.   template<Uint32 MutexId>
  55.   Mutex(Signal*, SimulatedBlock::MutexManager & mgr, MutexHandle2<MutexId> &);
  56.   
  57.   ~Mutex();
  58.   void release();
  59.   bool isNull() const ;
  60.   
  61.   bool lock(SimulatedBlock::Callback & callback);
  62.   bool trylock(SimulatedBlock::Callback & callback);
  63.   void unlock(SimulatedBlock::Callback & callback);
  64.   void unlock(); // Ignore callback
  65.   
  66.   bool create(SimulatedBlock::Callback & callback);
  67.   bool destroy(SimulatedBlock::Callback & callback);
  68. private:
  69.   Signal* m_signal;
  70.   SimulatedBlock::MutexManager & m_mgr;
  71.   const Uint32 m_mutexId;
  72.   Uint32 & m_srcPtrI;
  73.   SimulatedBlock::MutexManager::ActiveMutexPtr m_ptr;
  74.   
  75. public:
  76.   static void release(SimulatedBlock::MutexManager&, 
  77.       Uint32 activePtrI, Uint32 mutexId);
  78. };
  79. inline
  80. MutexHandle::MutexHandle(Uint32 id) : m_mutexId(id) { 
  81.   m_activeMutexPtrI = RNIL;
  82. }
  83. inline
  84. bool
  85. MutexHandle::isNull() const {
  86.   return m_activeMutexPtrI == RNIL;
  87. }
  88. inline
  89. void 
  90. MutexHandle::release(SimulatedBlock::MutexManager & mgr){
  91.   if(!isNull()){
  92.     Mutex::release(mgr, m_activeMutexPtrI, m_mutexId);
  93.     m_activeMutexPtrI = RNIL;
  94.   }
  95. }
  96. template<Uint32 MutexId>
  97. inline
  98. MutexHandle2<MutexId>::MutexHandle2() { 
  99.   m_activeMutexPtrI = RNIL;
  100. }
  101.   
  102. template<Uint32 MutexId>
  103. inline
  104. bool 
  105. MutexHandle2<MutexId>::isNull() const {
  106.   return m_activeMutexPtrI == RNIL;
  107. }
  108. template<Uint32 MutexId>
  109. inline
  110. void 
  111. MutexHandle2<MutexId>::release(SimulatedBlock::MutexManager & mgr){
  112.   if(!isNull()){
  113.     Mutex::release(mgr, m_activeMutexPtrI, MutexId);
  114.     m_activeMutexPtrI = RNIL;
  115.   }
  116. }
  117. inline
  118. Mutex::Mutex(Signal* signal, SimulatedBlock::MutexManager & mgr, 
  119.      MutexHandle & mh)
  120.   : m_signal(signal),
  121.     m_mgr(mgr),
  122.     m_mutexId(mh.m_mutexId),
  123.     m_srcPtrI(mh.m_activeMutexPtrI){
  124.   m_ptr.i = m_srcPtrI;
  125. }
  126. template<Uint32 MutexId>
  127. inline
  128. Mutex::Mutex(Signal* signal, SimulatedBlock::MutexManager & mgr, 
  129.      MutexHandle2<MutexId> & mh)
  130.   : m_signal(signal),
  131.     m_mgr(mgr),
  132.     m_mutexId(MutexId),
  133.     m_srcPtrI(mh.m_activeMutexPtrI){
  134.   
  135.   m_ptr.i = m_srcPtrI;
  136. }
  137. inline
  138. Mutex::~Mutex(){
  139.   m_srcPtrI = m_ptr.i;
  140. }
  141. inline
  142. void
  143. Mutex::release(){
  144.   if(!m_ptr.isNull()){
  145.     Mutex::release(m_mgr, m_ptr.i, m_mutexId);
  146.     m_ptr.setNull();
  147.   }
  148. }
  149. inline
  150. bool
  151. Mutex::isNull() const {
  152.   return m_ptr.isNull();
  153. }
  154. inline
  155. bool
  156. Mutex::lock(SimulatedBlock::Callback & callback){
  157.   if(m_ptr.isNull()){
  158.     if(m_mgr.seize(m_ptr)){
  159.       m_ptr.p->m_mutexId = m_mutexId;
  160.       m_ptr.p->m_callback = callback;
  161.       m_mgr.lock(m_signal, m_ptr);
  162.       return true;
  163.     }
  164.     return false;
  165.   }
  166.   ErrorReporter::handleAssert("Mutex::lock mutex alreay inuse", 
  167.       __FILE__, __LINE__);
  168.   return false;
  169. }
  170. inline
  171. bool
  172. Mutex::trylock(SimulatedBlock::Callback & callback){
  173.   if(m_ptr.isNull()){
  174.     if(m_mgr.seize(m_ptr)){
  175.       m_ptr.p->m_mutexId = m_mutexId;
  176.       m_ptr.p->m_callback = callback;
  177.       m_mgr.lock(m_signal, m_ptr);
  178.       return true;
  179.     }
  180.     return false;
  181.   }
  182.   ErrorReporter::handleAssert("Mutex::trylock mutex alreay inuse", 
  183.       __FILE__, __LINE__);
  184.   return false;
  185. }
  186. inline
  187. void
  188. Mutex::unlock(SimulatedBlock::Callback & callback){
  189.   if(!m_ptr.isNull()){
  190.     m_mgr.getPtr(m_ptr);
  191.     if(m_ptr.p->m_mutexId == m_mutexId){
  192.       m_ptr.p->m_callback = callback;
  193.       m_mgr.unlock(m_signal, m_ptr);
  194.       return;
  195.     }
  196.   }
  197.   ErrorReporter::handleAssert("Mutex::unlock invalid mutex", 
  198.       __FILE__, __LINE__);
  199. }
  200. inline
  201. bool
  202. Mutex::create(SimulatedBlock::Callback & callback){
  203.   if(m_ptr.isNull()){
  204.     if(m_mgr.seize(m_ptr)){
  205.       m_ptr.p->m_mutexId = m_mutexId;
  206.       m_ptr.p->m_callback = callback;
  207.       m_mgr.create(m_signal, m_ptr);
  208.       return true;
  209.     }
  210.     return false;
  211.   }
  212.   ErrorReporter::handleAssert("Mutex::create mutex alreay inuse", 
  213.       __FILE__, __LINE__);
  214.   return false;
  215. }
  216. inline
  217. bool
  218. Mutex::destroy(SimulatedBlock::Callback & callback){
  219.   if(m_ptr.isNull()){
  220.     if(m_mgr.seize(m_ptr)){
  221.       m_ptr.p->m_mutexId = m_mutexId;
  222.       m_ptr.p->m_callback = callback;
  223.       m_mgr.destroy(m_signal, m_ptr);
  224.       return true;
  225.     }
  226.     return false;
  227.   }
  228.   ErrorReporter::handleAssert("Mutex::destroy mutex alreay inuse", 
  229.       __FILE__, __LINE__);
  230.   return false;
  231. }
  232. #endif