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 static_mutex;
40
41 #define BOOST_STATIC_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER, }
42
43 class BOOST_REGEX_DECL scoped_static_mutex_lock
44 {
45 public:
46 scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
47 ~scoped_static_mutex_lock();
locked() const48 inline bool locked()const
49 {
50 return m_have_lock;
51 }
operator void const*() const52 inline operator void const*()const
53 {
54 return locked() ? this : 0;
55 }
56 void lock();
57 void unlock();
58 private:
59 static_mutex& m_mutex;
60 bool m_have_lock;
61 };
62
63 class static_mutex
64 {
65 public:
66 typedef scoped_static_mutex_lock scoped_lock;
67 pthread_mutex_t m_mutex;
68 };
69
70 } // namespace boost
71 #elif defined(BOOST_HAS_WINTHREADS)
72 //
73 // Win32 version:
74 // Use a 32-bit int as a lock, along with a test-and-set
75 // implementation using InterlockedCompareExchange.
76 //
77
78 #include <boost/cstdint.hpp>
79
80 namespace boost{
81
82 class BOOST_REGEX_DECL scoped_static_mutex_lock;
83
84 class static_mutex
85 {
86 public:
87 typedef scoped_static_mutex_lock scoped_lock;
88 boost::int32_t m_mutex;
89 };
90
91 #define BOOST_STATIC_MUTEX_INIT { 0, }
92
93 class BOOST_REGEX_DECL scoped_static_mutex_lock
94 {
95 public:
96 scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
97 ~scoped_static_mutex_lock();
operator void const*() const98 operator void const*()const
99 {
100 return locked() ? this : 0;
101 }
locked() const102 bool locked()const
103 {
104 return m_have_lock;
105 }
106 void lock();
107 void unlock();
108 private:
109 static_mutex& m_mutex;
110 bool m_have_lock;
111 scoped_static_mutex_lock(const scoped_static_mutex_lock&);
112 scoped_static_mutex_lock& operator=(const scoped_static_mutex_lock&);
113 };
114
115 } // namespace
116
117 #else
118 //
119 // Portable version of a static mutex based on Boost.Thread library:
120 // This has to use a single mutex shared by all instances of static_mutex
121 // because boost::call_once doesn't alow us to pass instance information
122 // down to the initialisation proceedure. In fact the initialisation routine
123 // may need to be called more than once - but only once per instance.
124 //
125 // Since this preprocessor path is almost never taken, we hide these header
126 // dependencies so that build tools don't find them.
127 //
128 #define BOOST_REGEX_H1 <boost/thread/once.hpp>
129 #define BOOST_REGEX_H2 <boost/thread/recursive_mutex.hpp>
130 #define BOOST_REGEX_H3 <boost/thread/lock_types.hpp>
131 #include BOOST_REGEX_H1
132 #include BOOST_REGEX_H2
133 #include BOOST_REGEX_H3
134 #undef BOOST_REGEX_H1
135 #undef BOOST_REGEX_H2
136 #undef BOOST_REGEX_H3
137
138 namespace boost{
139
140 class BOOST_REGEX_DECL scoped_static_mutex_lock;
141 extern "C" BOOST_REGEX_DECL void boost_regex_free_static_mutex();
142
143 class BOOST_REGEX_DECL static_mutex
144 {
145 public:
146 typedef scoped_static_mutex_lock scoped_lock;
147 static void init();
148 static boost::recursive_mutex* m_pmutex;
149 static boost::once_flag m_once;
150 };
151
152 #define BOOST_STATIC_MUTEX_INIT { }
153
154 class BOOST_REGEX_DECL scoped_static_mutex_lock
155 {
156 public:
157 scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
158 ~scoped_static_mutex_lock();
159 operator void const*()const;
160 bool locked()const;
161 void lock();
162 void unlock();
163 private:
164 boost::unique_lock<boost::recursive_mutex>* m_plock;
165 bool m_have_lock;
166 };
167
operator void const*() const168 inline scoped_static_mutex_lock::operator void const*()const
169 {
170 return locked() ? this : 0;
171 }
172
locked() const173 inline bool scoped_static_mutex_lock::locked()const
174 {
175 return m_have_lock;
176 }
177
178 } // namespace
179
180 #endif
181
182 #endif
183