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)
13 * LOCATION: see http://www.boost.org for most recent version.
14 * FILE static_mutex.cpp
15 * VERSION see <boost/version.hpp>
16 * DESCRIPTION: Declares static_mutex lock type.
19 #define BOOST_REGEX_SOURCE
20 #include <boost/regex/config.hpp>
22 #if defined(BOOST_REGEX_CXX03)
24 #include <boost/assert.hpp>
26 #ifdef BOOST_HAS_THREADS
28 #include <boost/regex/pending/static_mutex.hpp>
30 #if defined(BOOST_HAS_WINTHREADS)
34 #ifndef WIN32_LEAN_AND_MEAN
35 # define WIN32_LEAN_AND_MEAN
38 #include <boost/static_assert.hpp>
44 #if defined(BOOST_HAS_PTHREADS) && defined(PTHREAD_MUTEX_INITIALIZER)
46 scoped_static_mutex_lock::scoped_static_mutex_lock(static_mutex
& m
, bool lk
)
47 : m_mutex(m
), m_have_lock(false)
53 scoped_static_mutex_lock::~scoped_static_mutex_lock()
59 void scoped_static_mutex_lock::lock()
63 // Client code will throw if this fails:
64 m_have_lock
= (pthread_mutex_lock(&(m_mutex
.m_mutex
)) == 0);
68 void scoped_static_mutex_lock::unlock()
72 // If this fails there's nothing we can do except assert,
73 // exceptions are out of the question as this code is called
74 // from the lock's destructor:
75 BOOST_VERIFY(pthread_mutex_unlock(&(m_mutex
.m_mutex
)) == 0);
80 #elif defined(BOOST_HAS_WINTHREADS)
82 BOOST_STATIC_ASSERT(sizeof(LONG
) == sizeof(boost::int32_t));
84 scoped_static_mutex_lock::scoped_static_mutex_lock(static_mutex
& m
, bool lk
)
85 : m_mutex(m
), m_have_lock(false)
91 scoped_static_mutex_lock::~scoped_static_mutex_lock()
97 void scoped_static_mutex_lock::lock()
101 #if !defined(InterlockedCompareExchangePointer)
102 while(0 != InterlockedCompareExchange(reinterpret_cast<void**>((boost::uint_least16_t*)&(m_mutex
.m_mutex
)), (void*)1, 0))
104 while(0 != InterlockedCompareExchange(reinterpret_cast<LONG
*>(&(m_mutex
.m_mutex
)), 1, 0))
113 void scoped_static_mutex_lock::unlock()
117 #if !defined(InterlockedCompareExchangePointer)
118 InterlockedExchange((LONG
*)&(m_mutex
.m_mutex
), 0);
120 InterlockedExchange(reinterpret_cast<LONG
*>(&(m_mutex
.m_mutex
)), 0);
128 // Portable version of a static mutex based on Boost.Thread library:
131 #include <boost/assert.hpp>
133 boost::recursive_mutex
* static_mutex::m_pmutex
= 0;
134 boost::once_flag
static_mutex::m_once
= BOOST_ONCE_INIT
;
136 extern "C" BOOST_REGEX_DECL
void boost_regex_free_static_mutex()
138 delete static_mutex::m_pmutex
;
139 static_mutex::m_pmutex
= 0;
142 void static_mutex::init()
144 m_pmutex
= new boost::recursive_mutex();
145 int r
= atexit(boost_regex_free_static_mutex
);
146 BOOST_ASSERT(0 == r
);
149 scoped_static_mutex_lock::scoped_static_mutex_lock(static_mutex
& , bool lk
)
150 : m_plock(0), m_have_lock(false)
156 scoped_static_mutex_lock::~scoped_static_mutex_lock()
163 void scoped_static_mutex_lock::lock()
167 boost::call_once(static_mutex::m_once
,&static_mutex::init
);
169 m_plock
= new boost::unique_lock
<boost::recursive_mutex
>(*static_mutex::m_pmutex
, boost::defer_lock
);
175 void scoped_static_mutex_lock::unlock()
188 #endif // BOOST_HAS_THREADS