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/config.hpp>
21 #include <boost/assert.hpp>
23 #ifdef BOOST_HAS_THREADS
25 #include <boost/regex/pending/static_mutex.hpp>
27 #if defined(BOOST_HAS_WINTHREADS)
31 #ifndef WIN32_LEAN_AND_MEAN
32 # define WIN32_LEAN_AND_MEAN
35 #include <boost/static_assert.hpp>
41 #if defined(BOOST_HAS_PTHREADS) && defined(PTHREAD_MUTEX_INITIALIZER)
43 scoped_static_mutex_lock::scoped_static_mutex_lock(static_mutex& m, bool lk)
44 : m_mutex(m), m_have_lock(false)
50 scoped_static_mutex_lock::~scoped_static_mutex_lock()
56 void scoped_static_mutex_lock::lock()
60 // Client code will throw if this fails:
61 m_have_lock = (pthread_mutex_lock(&(m_mutex.m_mutex)) == 0);
65 void scoped_static_mutex_lock::unlock()
69 // If this fails there's nothing we can do except assert,
70 // exceptions are out of the question as this code is called
71 // from the lock's destructor:
72 BOOST_VERIFY(pthread_mutex_unlock(&(m_mutex.m_mutex)) == 0);
77 #elif defined(BOOST_HAS_WINTHREADS)
79 BOOST_STATIC_ASSERT(sizeof(LONG) == sizeof(boost::int32_t));
81 scoped_static_mutex_lock::scoped_static_mutex_lock(static_mutex& m, bool lk)
82 : m_mutex(m), m_have_lock(false)
88 scoped_static_mutex_lock::~scoped_static_mutex_lock()
94 void scoped_static_mutex_lock::lock()
98 #if !defined(InterlockedCompareExchangePointer)
99 while(0 != InterlockedCompareExchange(reinterpret_cast<void**>((boost::uint_least16_t*)&(m_mutex.m_mutex)), (void*)1, 0))
101 while(0 != InterlockedCompareExchange(reinterpret_cast<LONG*>(&(m_mutex.m_mutex)), 1, 0))
110 void scoped_static_mutex_lock::unlock()
114 #if !defined(InterlockedCompareExchangePointer)
115 InterlockedExchange((LONG*)&(m_mutex.m_mutex), 0);
117 InterlockedExchange(reinterpret_cast<LONG*>(&(m_mutex.m_mutex)), 0);
125 // Portable version of a static mutex based on Boost.Thread library:
128 #include <boost/assert.hpp>
130 boost::recursive_mutex* static_mutex::m_pmutex = 0;
131 boost::once_flag static_mutex::m_once = BOOST_ONCE_INIT;
133 extern "C" BOOST_REGEX_DECL void boost_regex_free_static_mutex()
135 delete static_mutex::m_pmutex;
136 static_mutex::m_pmutex = 0;
139 void static_mutex::init()
141 m_pmutex = new boost::recursive_mutex();
142 int r = atexit(boost_regex_free_static_mutex);
143 BOOST_ASSERT(0 == r);
146 scoped_static_mutex_lock::scoped_static_mutex_lock(static_mutex& , bool lk)
147 : m_plock(0), m_have_lock(false)
153 scoped_static_mutex_lock::~scoped_static_mutex_lock()
160 void scoped_static_mutex_lock::lock()
164 boost::call_once(static_mutex::m_once,&static_mutex::init);
166 m_plock = new boost::unique_lock<boost::recursive_mutex>(*static_mutex::m_pmutex, boost::defer_lock);
172 void scoped_static_mutex_lock::unlock()
185 #endif // BOOST_HAS_THREADS