/src/contrib/boost/thread/pthread/mutex.hpp

http://pythonocc.googlecode.com/ · C++ Header · 211 lines · 182 code · 25 blank · 4 comment · 10 complexity · 852b479f168265679655b3b7b630ad8e MD5 · raw file

  1. #ifndef BOOST_THREAD_PTHREAD_MUTEX_HPP
  2. #define BOOST_THREAD_PTHREAD_MUTEX_HPP
  3. // (C) Copyright 2007-8 Anthony Williams
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. #include <pthread.h>
  8. #include <boost/utility.hpp>
  9. #include <boost/throw_exception.hpp>
  10. #include <boost/thread/exceptions.hpp>
  11. #include <boost/thread/locks.hpp>
  12. #include <boost/thread/thread_time.hpp>
  13. #include <boost/thread/xtime.hpp>
  14. #include <boost/assert.hpp>
  15. #include <errno.h>
  16. #include "timespec.hpp"
  17. #include "pthread_mutex_scoped_lock.hpp"
  18. #ifdef _POSIX_TIMEOUTS
  19. #if _POSIX_TIMEOUTS >= 0
  20. #define BOOST_PTHREAD_HAS_TIMEDLOCK
  21. #endif
  22. #endif
  23. #include <boost/config/abi_prefix.hpp>
  24. namespace boost
  25. {
  26. class mutex:
  27. boost::noncopyable
  28. {
  29. private:
  30. pthread_mutex_t m;
  31. public:
  32. mutex()
  33. {
  34. int const res=pthread_mutex_init(&m,NULL);
  35. if(res)
  36. {
  37. boost::throw_exception(thread_resource_error());
  38. }
  39. }
  40. ~mutex()
  41. {
  42. BOOST_VERIFY(!pthread_mutex_destroy(&m));
  43. }
  44. void lock()
  45. {
  46. BOOST_VERIFY(!pthread_mutex_lock(&m));
  47. }
  48. void unlock()
  49. {
  50. BOOST_VERIFY(!pthread_mutex_unlock(&m));
  51. }
  52. bool try_lock()
  53. {
  54. int const res=pthread_mutex_trylock(&m);
  55. BOOST_ASSERT(!res || res==EBUSY);
  56. return !res;
  57. }
  58. typedef pthread_mutex_t* native_handle_type;
  59. native_handle_type native_handle()
  60. {
  61. return &m;
  62. }
  63. typedef unique_lock<mutex> scoped_lock;
  64. typedef detail::try_lock_wrapper<mutex> scoped_try_lock;
  65. };
  66. typedef mutex try_mutex;
  67. class timed_mutex:
  68. boost::noncopyable
  69. {
  70. private:
  71. pthread_mutex_t m;
  72. #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
  73. pthread_cond_t cond;
  74. bool is_locked;
  75. #endif
  76. public:
  77. timed_mutex()
  78. {
  79. int const res=pthread_mutex_init(&m,NULL);
  80. if(res)
  81. {
  82. boost::throw_exception(thread_resource_error());
  83. }
  84. #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
  85. int const res2=pthread_cond_init(&cond,NULL);
  86. if(res2)
  87. {
  88. BOOST_VERIFY(!pthread_mutex_destroy(&m));
  89. boost::throw_exception(thread_resource_error());
  90. }
  91. is_locked=false;
  92. #endif
  93. }
  94. ~timed_mutex()
  95. {
  96. BOOST_VERIFY(!pthread_mutex_destroy(&m));
  97. #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
  98. BOOST_VERIFY(!pthread_cond_destroy(&cond));
  99. #endif
  100. }
  101. template<typename TimeDuration>
  102. bool timed_lock(TimeDuration const & relative_time)
  103. {
  104. return timed_lock(get_system_time()+relative_time);
  105. }
  106. bool timed_lock(boost::xtime const & absolute_time)
  107. {
  108. return timed_lock(system_time(absolute_time));
  109. }
  110. #ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
  111. void lock()
  112. {
  113. BOOST_VERIFY(!pthread_mutex_lock(&m));
  114. }
  115. void unlock()
  116. {
  117. BOOST_VERIFY(!pthread_mutex_unlock(&m));
  118. }
  119. bool try_lock()
  120. {
  121. int const res=pthread_mutex_trylock(&m);
  122. BOOST_ASSERT(!res || res==EBUSY);
  123. return !res;
  124. }
  125. bool timed_lock(system_time const & abs_time)
  126. {
  127. struct timespec const timeout=detail::get_timespec(abs_time);
  128. int const res=pthread_mutex_timedlock(&m,&timeout);
  129. BOOST_ASSERT(!res || res==ETIMEDOUT);
  130. return !res;
  131. }
  132. typedef pthread_mutex_t* native_handle_type;
  133. native_handle_type native_handle()
  134. {
  135. return &m;
  136. }
  137. #else
  138. void lock()
  139. {
  140. boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
  141. while(is_locked)
  142. {
  143. BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
  144. }
  145. is_locked=true;
  146. }
  147. void unlock()
  148. {
  149. boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
  150. is_locked=false;
  151. BOOST_VERIFY(!pthread_cond_signal(&cond));
  152. }
  153. bool try_lock()
  154. {
  155. boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
  156. if(is_locked)
  157. {
  158. return false;
  159. }
  160. is_locked=true;
  161. return true;
  162. }
  163. bool timed_lock(system_time const & abs_time)
  164. {
  165. struct timespec const timeout=detail::get_timespec(abs_time);
  166. boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
  167. while(is_locked)
  168. {
  169. int const cond_res=pthread_cond_timedwait(&cond,&m,&timeout);
  170. if(cond_res==ETIMEDOUT)
  171. {
  172. return false;
  173. }
  174. BOOST_ASSERT(!cond_res);
  175. }
  176. is_locked=true;
  177. return true;
  178. }
  179. #endif
  180. typedef unique_lock<timed_mutex> scoped_timed_lock;
  181. typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;
  182. typedef scoped_timed_lock scoped_lock;
  183. };
  184. }
  185. #include <boost/config/abi_suffix.hpp>
  186. #endif