static_mutex.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. *
  3. * Copyright (c) 2004
  4. * John Maddock
  5. *
  6. * Use, modification and distribution are subject to the
  7. * Boost Software License, Version 1.0. (See accompanying file
  8. * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. *
  10. */
  11. /*
  12. * LOCATION: see http://www.boost.org for most recent version.
  13. * FILE static_mutex.hpp
  14. * VERSION see <boost/version.hpp>
  15. * DESCRIPTION: Declares static_mutex lock type, there are three different
  16. * implementations: POSIX pthreads, WIN32 threads, and portable,
  17. * these are described in more detail below.
  18. */
  19. #ifndef BOOST_REGEX_STATIC_MUTEX_HPP
  20. #define BOOST_REGEX_STATIC_MUTEX_HPP
  21. #include <boost/config.hpp>
  22. #include <boost/regex/config.hpp> // dll import/export options.
  23. #ifdef BOOST_HAS_PTHREADS
  24. #include <pthread.h>
  25. #endif
  26. #if defined(BOOST_HAS_PTHREADS) && defined(PTHREAD_MUTEX_INITIALIZER)
  27. //
  28. // pthreads version:
  29. // simple wrap around a pthread_mutex_t initialized with
  30. // PTHREAD_MUTEX_INITIALIZER.
  31. //
  32. namespace boost{
  33. class BOOST_REGEX_DECL scoped_static_mutex_lock;
  34. class static_mutex
  35. {
  36. public:
  37. typedef scoped_static_mutex_lock scoped_lock;
  38. pthread_mutex_t m_mutex;
  39. };
  40. #define BOOST_STATIC_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER, }
  41. class BOOST_REGEX_DECL scoped_static_mutex_lock
  42. {
  43. public:
  44. scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
  45. ~scoped_static_mutex_lock();
  46. inline bool locked()const
  47. {
  48. return m_have_lock;
  49. }
  50. inline operator void const*()const
  51. {
  52. return locked() ? this : 0;
  53. }
  54. void lock();
  55. void unlock();
  56. private:
  57. static_mutex& m_mutex;
  58. bool m_have_lock;
  59. };
  60. } // namespace boost
  61. #elif defined(BOOST_HAS_WINTHREADS)
  62. //
  63. // Win32 version:
  64. // Use a 32-bit int as a lock, along with a test-and-set
  65. // implementation using InterlockedCompareExchange.
  66. //
  67. #include <boost/cstdint.hpp>
  68. namespace boost{
  69. class BOOST_REGEX_DECL scoped_static_mutex_lock;
  70. class static_mutex
  71. {
  72. public:
  73. typedef scoped_static_mutex_lock scoped_lock;
  74. boost::int32_t m_mutex;
  75. };
  76. #define BOOST_STATIC_MUTEX_INIT { 0, }
  77. class BOOST_REGEX_DECL scoped_static_mutex_lock
  78. {
  79. public:
  80. scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
  81. ~scoped_static_mutex_lock();
  82. operator void const*()const;
  83. bool locked()const;
  84. void lock();
  85. void unlock();
  86. private:
  87. static_mutex& m_mutex;
  88. bool m_have_lock;
  89. scoped_static_mutex_lock(const scoped_static_mutex_lock&);
  90. scoped_static_mutex_lock& operator=(const scoped_static_mutex_lock&);
  91. };
  92. inline scoped_static_mutex_lock::operator void const*()const
  93. {
  94. return locked() ? this : 0;
  95. }
  96. inline bool scoped_static_mutex_lock::locked()const
  97. {
  98. return m_have_lock;
  99. }
  100. } // namespace
  101. #else
  102. //
  103. // Portable version of a static mutex based on Boost.Thread library:
  104. // This has to use a single mutex shared by all instances of static_mutex
  105. // because boost::call_once doesn't alow us to pass instance information
  106. // down to the initialisation proceedure. In fact the initialisation routine
  107. // may need to be called more than once - but only once per instance.
  108. //
  109. // Since this preprocessor path is almost never taken, we hide these header
  110. // dependencies so that build tools don't find them.
  111. //
  112. #define B1 <boost/thread/once.hpp>
  113. #define B2 <boost/thread/recursive_mutex.hpp>
  114. #include B1
  115. #include B2
  116. #undef B1
  117. #undef B2
  118. namespace boost{
  119. class BOOST_REGEX_DECL scoped_static_mutex_lock;
  120. extern "C" BOOST_REGEX_DECL void free_static_mutex();
  121. class BOOST_REGEX_DECL static_mutex
  122. {
  123. public:
  124. typedef scoped_static_mutex_lock scoped_lock;
  125. static void init();
  126. static boost::recursive_mutex* m_pmutex;
  127. static boost::once_flag m_once;
  128. };
  129. #define BOOST_STATIC_MUTEX_INIT { }
  130. class BOOST_REGEX_DECL scoped_static_mutex_lock
  131. {
  132. public:
  133. scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
  134. ~scoped_static_mutex_lock();
  135. operator void const*()const;
  136. bool locked()const;
  137. void lock();
  138. void unlock();
  139. private:
  140. boost::recursive_mutex::scoped_lock* m_plock;
  141. bool m_have_lock;
  142. };
  143. inline scoped_static_mutex_lock::operator void const*()const
  144. {
  145. return locked() ? this : 0;
  146. }
  147. inline bool scoped_static_mutex_lock::locked()const
  148. {
  149. return m_have_lock;
  150. }
  151. } // namespace
  152. #endif
  153. #endif