lock_concepts.hpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. // (C) Copyright 2012 Vicente Botet
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_THREAD_LOCK_CONCEPTS_HPP
  6. #define BOOST_THREAD_LOCK_CONCEPTS_HPP
  7. #include <boost/thread/lock_traits.hpp>
  8. #include <boost/thread/lock_options.hpp>
  9. #include <boost/thread/lockable_concepts.hpp>
  10. #include <boost/thread/exceptions.hpp>
  11. #include <boost/thread/detail/move.hpp>
  12. #include <boost/chrono/chrono.hpp>
  13. #include <boost/concept_check.hpp>
  14. #include <boost/static_assert.hpp>
  15. namespace boost
  16. {
  17. /**
  18. * BasicLock object supports the basic features
  19. * required to delimit a critical region
  20. * Supports the basic lock, unlock and try_lock functions and
  21. * defines the lock traits
  22. */
  23. template <typename Lk>
  24. struct BasicLock
  25. {
  26. typedef typename Lk::mutex_type mutex_type;
  27. void cvt_mutex_ptr(mutex_type*) {}
  28. BOOST_CONCEPT_ASSERT(( BasicLockable<mutex_type> ));
  29. BOOST_CONCEPT_USAGE(BasicLock)
  30. {
  31. const Lk l1(mtx);
  32. Lk l2(mtx, defer_lock);
  33. Lk l3(mtx, adopt_lock);
  34. Lk l4(( Lk()));
  35. Lk l5(( boost::move(l2)));
  36. cvt_mutex_ptr(l1.mutex());
  37. if (l1.owns_lock()) return;
  38. if (l1) return;
  39. if (!l1) return;
  40. l2.lock();
  41. l2.unlock();
  42. l2.release();
  43. }
  44. BasicLock() :
  45. mtx(*static_cast<mutex_type*>(0))
  46. {}
  47. private:
  48. BasicLock operator=(BasicLock const&);
  49. mutex_type& mtx;
  50. }
  51. ;
  52. template <typename Lk>
  53. struct Lock
  54. {
  55. BOOST_CONCEPT_ASSERT(( BasicLock<Lk> ));
  56. typedef typename Lk::mutex_type mutex_type;
  57. BOOST_CONCEPT_ASSERT(( Lockable<mutex_type> ));
  58. BOOST_CONCEPT_USAGE(Lock)
  59. {
  60. Lk l1(mtx, try_to_lock);
  61. if (l1.try_lock()) return;
  62. }
  63. Lock() :
  64. mtx(*static_cast<mutex_type*>(0))
  65. {}
  66. private:
  67. Lock operator=(Lock const&);
  68. mutex_type& mtx;
  69. };
  70. template <typename Lk>
  71. struct TimedLock
  72. {
  73. BOOST_CONCEPT_ASSERT(( Lock<Lk> ));
  74. typedef typename Lk::mutex_type mutex_type;
  75. BOOST_CONCEPT_ASSERT(( TimedLockable<mutex_type> ));
  76. BOOST_CONCEPT_USAGE(TimedLock)
  77. {
  78. const Lk l1(mtx, t);
  79. Lk l2(mtx, d);
  80. if (l1.try_lock_until(t)) return;
  81. if (l1.try_lock_for(d)) return;
  82. }
  83. TimedLock() :
  84. mtx(*static_cast<mutex_type*>(0))
  85. {}
  86. private:
  87. TimedLock operator=(TimedLock const&);
  88. mutex_type& mtx;
  89. boost::chrono::system_clock::time_point t;
  90. boost::chrono::system_clock::duration d;
  91. };
  92. template <typename Lk>
  93. struct UniqueLock
  94. {
  95. BOOST_CONCEPT_ASSERT(( TimedLock<Lk> ));
  96. typedef typename Lk::mutex_type mutex_type;
  97. BOOST_CONCEPT_USAGE(UniqueLock)
  98. {
  99. }
  100. UniqueLock() :
  101. mtx(*static_cast<mutex_type*>(0))
  102. {}
  103. private:
  104. UniqueLock operator=(UniqueLock const&);
  105. mutex_type& mtx;
  106. };
  107. template <typename Lk>
  108. struct SharedLock
  109. {
  110. BOOST_CONCEPT_ASSERT(( TimedLock<Lk> ));
  111. typedef typename Lk::mutex_type mutex_type;
  112. BOOST_CONCEPT_USAGE(SharedLock)
  113. {
  114. }
  115. SharedLock() :
  116. mtx(*static_cast<mutex_type*>(0))
  117. {}
  118. private:
  119. SharedLock operator=(SharedLock const&);
  120. mutex_type& mtx;
  121. };
  122. template <typename Lk>
  123. struct UpgradeLock
  124. {
  125. BOOST_CONCEPT_ASSERT(( SharedLock<Lk> ));
  126. typedef typename Lk::mutex_type mutex_type;
  127. BOOST_CONCEPT_USAGE(UpgradeLock)
  128. {
  129. }
  130. UpgradeLock() :
  131. mtx(*static_cast<mutex_type*>(0))
  132. {}
  133. private:
  134. UpgradeLock operator=(UpgradeLock const&);
  135. mutex_type& mtx;
  136. };
  137. /**
  138. * An StrictLock is a scoped lock guard ensuring the mutex is locked on the
  139. * scope of the lock, by locking the mutex on construction and unlocking it on
  140. * destruction.
  141. *
  142. * Essentially, a StrictLock's role is only to live on the stack as an
  143. * automatic variable. strict_lock must adhere to a non-copy and non-alias
  144. * policy. StrictLock disables copying by making the copy constructor and the
  145. * assignment operator private. While we're at it, let's disable operator new
  146. * and operator delete; strict locks are not intended to be allocated on the
  147. * heap. StrictLock avoids aliasing by using a slightly less orthodox and
  148. * less well-known technique: disable address taking.
  149. */
  150. template <typename Lk>
  151. struct StrictLock
  152. {
  153. typedef typename Lk::mutex_type mutex_type;
  154. BOOST_CONCEPT_ASSERT(( BasicLockable<mutex_type> ));
  155. BOOST_STATIC_ASSERT(( is_strict_lock<Lk>::value ));
  156. BOOST_CONCEPT_USAGE( StrictLock)
  157. {
  158. if (l1.owns_lock(&mtx)) return;
  159. }
  160. StrictLock() :
  161. l1(*static_cast<Lk*>(0)),
  162. mtx(*static_cast<mutex_type*>(0))
  163. {}
  164. private:
  165. StrictLock operator=(StrictLock const&);
  166. Lk const& l1;
  167. mutex_type const& mtx;
  168. };
  169. }
  170. #endif