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