static_mutex.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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 static_mutex;
  34. #define BOOST_STATIC_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER, }
  35. class BOOST_REGEX_DECL scoped_static_mutex_lock
  36. {
  37. public:
  38. scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
  39. ~scoped_static_mutex_lock();
  40. inline bool locked()const
  41. {
  42. return m_have_lock;
  43. }
  44. inline operator void const*()const
  45. {
  46. return locked() ? this : 0;
  47. }
  48. void lock();
  49. void unlock();
  50. private:
  51. static_mutex& m_mutex;
  52. bool m_have_lock;
  53. };
  54. class static_mutex
  55. {
  56. public:
  57. typedef scoped_static_mutex_lock scoped_lock;
  58. pthread_mutex_t m_mutex;
  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. {
  84. return locked() ? this : 0;
  85. }
  86. bool locked()const
  87. {
  88. return m_have_lock;
  89. }
  90. void lock();
  91. void unlock();
  92. private:
  93. static_mutex& m_mutex;
  94. bool m_have_lock;
  95. scoped_static_mutex_lock(const scoped_static_mutex_lock&);
  96. scoped_static_mutex_lock& operator=(const scoped_static_mutex_lock&);
  97. };
  98. } // namespace
  99. #else
  100. //
  101. // Portable version of a static mutex based on Boost.Thread library:
  102. // This has to use a single mutex shared by all instances of static_mutex
  103. // because boost::call_once doesn't alow us to pass instance information
  104. // down to the initialisation proceedure. In fact the initialisation routine
  105. // may need to be called more than once - but only once per instance.
  106. //
  107. // Since this preprocessor path is almost never taken, we hide these header
  108. // dependencies so that build tools don't find them.
  109. //
  110. #define BOOST_REGEX_H1 <boost/thread/once.hpp>
  111. #define BOOST_REGEX_H2 <boost/thread/recursive_mutex.hpp>
  112. #define BOOST_REGEX_H3 <boost/thread/lock_types.hpp>
  113. #include BOOST_REGEX_H1
  114. #include BOOST_REGEX_H2
  115. #include BOOST_REGEX_H3
  116. #undef BOOST_REGEX_H1
  117. #undef BOOST_REGEX_H2
  118. #undef BOOST_REGEX_H3
  119. namespace boost{
  120. class BOOST_REGEX_DECL scoped_static_mutex_lock;
  121. extern "C" BOOST_REGEX_DECL void boost_regex_free_static_mutex();
  122. class BOOST_REGEX_DECL static_mutex
  123. {
  124. public:
  125. typedef scoped_static_mutex_lock scoped_lock;
  126. static void init();
  127. static boost::recursive_mutex* m_pmutex;
  128. static boost::once_flag m_once;
  129. };
  130. #define BOOST_STATIC_MUTEX_INIT { }
  131. class BOOST_REGEX_DECL scoped_static_mutex_lock
  132. {
  133. public:
  134. scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
  135. ~scoped_static_mutex_lock();
  136. operator void const*()const;
  137. bool locked()const;
  138. void lock();
  139. void unlock();
  140. private:
  141. boost::unique_lock<boost::recursive_mutex>* m_plock;
  142. bool m_have_lock;
  143. };
  144. inline scoped_static_mutex_lock::operator void const*()const
  145. {
  146. return locked() ? this : 0;
  147. }
  148. inline bool scoped_static_mutex_lock::locked()const
  149. {
  150. return m_have_lock;
  151. }
  152. } // namespace
  153. #endif
  154. #endif