• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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