ExclusiveHolder.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. #include <memory>
  2. #include <mutex>
  3. //-----------------------------------------------------------------------------
  4. // 允许互斥访问一个指针对象
  5. //-----------------------------------------------------------------------------
  6. template <typename T> class ExclusiveHolder
  7. {
  8. protected:
  9. T * m_pObject;
  10. public:
  11. ExclusiveHolder ();
  12. explicit ExclusiveHolder (T * object);
  13. virtual ~ExclusiveHolder ();
  14. private:
  15. // 禁止拷贝构造函数
  16. ExclusiveHolder (const ExclusiveHolder & h) = delete;
  17. // 禁止复制
  18. ExclusiveHolder & operator = (const ExclusiveHolder & h) = delete;
  19. public:
  20. void Attach (T * object);
  21. T * Detach ();
  22. ExclusiveHolder & operator = (T * object);
  23. bool IsEmpty () const;
  24. void Release ();
  25. protected:
  26. mutable std::recursive_mutex m_Mutex;
  27. public:
  28. class LockHolder
  29. {
  30. public:
  31. LockHolder (const ExclusiveHolder * holder);
  32. ~LockHolder ();
  33. LockHolder (LockHolder && from);
  34. private:
  35. // 可以对同一个 ExclusiveHolder 对象反复调用 Lock, 但是 LockHolder 还是不要拷贝构造了吧
  36. // 禁止拷贝构造函数
  37. LockHolder (const LockHolder & h) = delete;
  38. // 禁止复制
  39. LockHolder & operator = (const LockHolder & h) = delete;
  40. public:
  41. T * As ();
  42. const T * As () const;
  43. template <typename C> C * AS ();
  44. template <typename C> const C * AS () const;
  45. T * operator -> ()
  46. {
  47. return As ();
  48. }
  49. const T * operator -> () const
  50. {
  51. return As ();
  52. }
  53. T & operator * ()
  54. {
  55. return *As ();
  56. }
  57. const T & operator * () const
  58. {
  59. return *As ();
  60. }
  61. protected:
  62. std::unique_ptr <std::lock_guard < std::recursive_mutex > > m_Lock;
  63. const ExclusiveHolder * m_Holder;
  64. };
  65. public:
  66. inline LockHolder Lock ()
  67. {
  68. return LockHolder (this);
  69. }
  70. inline LockHolder Lock () const
  71. {
  72. return LockHolder (this);
  73. }
  74. template <class Action> void LockExec (Action action)
  75. {
  76. LockHolder holder (this);
  77. action (holder.As ());
  78. }
  79. template <class Action> void LockExec (Action action) const
  80. {
  81. LockHolder holder (this);
  82. action (holder.As ());
  83. }
  84. };
  85. template <typename T>
  86. ExclusiveHolder <T>::ExclusiveHolder()
  87. {
  88. m_pObject = NULL;
  89. }
  90. template <typename T>
  91. ExclusiveHolder <T>::~ExclusiveHolder()
  92. {
  93. LockHolder Lock(this);
  94. delete m_pObject;
  95. }
  96. template <typename T>
  97. ExclusiveHolder <T>::ExclusiveHolder(T* object)
  98. {
  99. m_pObject = object;
  100. }
  101. template <typename T>
  102. void ExclusiveHolder <T>::Attach(T* object)
  103. {
  104. LockHolder Lock(this);
  105. delete m_pObject;
  106. m_pObject = object;
  107. }
  108. template <typename T>
  109. T* ExclusiveHolder <T>::Detach()
  110. {
  111. LockHolder Lock(this);
  112. T* old = m_pObject;
  113. m_pObject = NULL;
  114. Release();
  115. return old;
  116. }
  117. template <typename T>
  118. void ExclusiveHolder <T>::Release()
  119. {
  120. LockHolder Lock(this);
  121. delete m_pObject;
  122. m_pObject = NULL;
  123. }
  124. template <typename T>
  125. ExclusiveHolder <T>& ExclusiveHolder <T>::operator = (T* object)
  126. {
  127. Attach(object);
  128. return *this;
  129. }
  130. template <typename T>
  131. bool ExclusiveHolder <T>::IsEmpty() const
  132. {
  133. LockHolder Lock(this);
  134. return (m_pObject == NULL);
  135. }
  136. template <typename T>
  137. ExclusiveHolder <T>::LockHolder::LockHolder(const ExclusiveHolder <T>* holder)
  138. {
  139. auto lock = new std::lock_guard < std::recursive_mutex >(holder->m_Mutex);
  140. m_Lock.reset(lock);
  141. m_Holder = holder;
  142. }
  143. template <typename T>
  144. ExclusiveHolder <T>::LockHolder::LockHolder(LockHolder&& from)
  145. {
  146. m_Lock.swap(from.m_Lock);
  147. m_Holder = from.m_Holder;
  148. }
  149. template <typename T>
  150. ExclusiveHolder <T>::LockHolder::~LockHolder()
  151. {
  152. }
  153. template <typename T>
  154. T* ExclusiveHolder <T>::LockHolder::As()
  155. {
  156. return m_Holder->m_pObject;
  157. }
  158. template <typename T>
  159. const T* ExclusiveHolder <T>::LockHolder::As() const
  160. {
  161. return m_Holder->m_pObject;
  162. }
  163. template <typename T>
  164. template <typename C> C* ExclusiveHolder <T>::LockHolder::AS()
  165. {
  166. return m_Holder->m_pObject;
  167. }
  168. template <typename T>
  169. template <typename C> const C* ExclusiveHolder <T>::LockHolder::AS() const
  170. {
  171. return m_Holder->m_pObject;
  172. }