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