Chris@16: /* Chris@16: * Chris@16: * Copyright (c) 2004 Chris@16: * John Maddock Chris@16: * Chris@16: * Use, modification and distribution are subject to the Chris@16: * Boost Software License, Version 1.0. (See accompanying file Chris@16: * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: * Chris@16: */ Chris@16: Chris@16: /* Chris@16: * LOCATION: see http://www.boost.org for most recent version. Chris@16: * FILE static_mutex.hpp Chris@16: * VERSION see Chris@16: * DESCRIPTION: Declares static_mutex lock type, there are three different Chris@16: * implementations: POSIX pthreads, WIN32 threads, and portable, Chris@16: * these are described in more detail below. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_REGEX_STATIC_MUTEX_HPP Chris@16: #define BOOST_REGEX_STATIC_MUTEX_HPP Chris@16: Chris@16: #include Chris@16: #include // dll import/export options. Chris@16: Chris@16: #ifdef BOOST_HAS_PTHREADS Chris@16: #include Chris@16: #endif Chris@16: Chris@16: #if defined(BOOST_HAS_PTHREADS) && defined(PTHREAD_MUTEX_INITIALIZER) Chris@16: // Chris@16: // pthreads version: Chris@16: // simple wrap around a pthread_mutex_t initialized with Chris@16: // PTHREAD_MUTEX_INITIALIZER. Chris@16: // Chris@16: namespace boost{ Chris@16: Chris@16: class static_mutex; Chris@16: Chris@16: #define BOOST_STATIC_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER, } Chris@16: Chris@16: class BOOST_REGEX_DECL scoped_static_mutex_lock Chris@16: { Chris@16: public: Chris@16: scoped_static_mutex_lock(static_mutex& mut, bool lk = true); Chris@16: ~scoped_static_mutex_lock(); Chris@16: inline bool locked()const Chris@16: { Chris@16: return m_have_lock; Chris@16: } Chris@16: inline operator void const*()const Chris@16: { Chris@16: return locked() ? this : 0; Chris@16: } Chris@16: void lock(); Chris@16: void unlock(); Chris@16: private: Chris@16: static_mutex& m_mutex; Chris@16: bool m_have_lock; Chris@16: }; Chris@16: Chris@16: class static_mutex Chris@16: { Chris@16: public: Chris@16: typedef scoped_static_mutex_lock scoped_lock; Chris@16: pthread_mutex_t m_mutex; Chris@16: }; Chris@16: Chris@16: } // namespace boost Chris@16: #elif defined(BOOST_HAS_WINTHREADS) Chris@16: // Chris@16: // Win32 version: Chris@16: // Use a 32-bit int as a lock, along with a test-and-set Chris@16: // implementation using InterlockedCompareExchange. Chris@16: // Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost{ Chris@16: Chris@16: class BOOST_REGEX_DECL scoped_static_mutex_lock; Chris@16: Chris@16: class static_mutex Chris@16: { Chris@16: public: Chris@16: typedef scoped_static_mutex_lock scoped_lock; Chris@16: boost::int32_t m_mutex; Chris@16: }; Chris@16: Chris@16: #define BOOST_STATIC_MUTEX_INIT { 0, } Chris@16: Chris@16: class BOOST_REGEX_DECL scoped_static_mutex_lock Chris@16: { Chris@16: public: Chris@16: scoped_static_mutex_lock(static_mutex& mut, bool lk = true); Chris@16: ~scoped_static_mutex_lock(); Chris@16: operator void const*()const Chris@16: { Chris@16: return locked() ? this : 0; Chris@16: } Chris@16: bool locked()const Chris@16: { Chris@16: return m_have_lock; Chris@16: } Chris@16: void lock(); Chris@16: void unlock(); Chris@16: private: Chris@16: static_mutex& m_mutex; Chris@16: bool m_have_lock; Chris@16: scoped_static_mutex_lock(const scoped_static_mutex_lock&); Chris@16: scoped_static_mutex_lock& operator=(const scoped_static_mutex_lock&); Chris@16: }; Chris@16: Chris@16: } // namespace Chris@16: Chris@16: #else Chris@16: // Chris@16: // Portable version of a static mutex based on Boost.Thread library: Chris@16: // This has to use a single mutex shared by all instances of static_mutex Chris@16: // because boost::call_once doesn't alow us to pass instance information Chris@16: // down to the initialisation proceedure. In fact the initialisation routine Chris@16: // may need to be called more than once - but only once per instance. Chris@16: // Chris@16: // Since this preprocessor path is almost never taken, we hide these header Chris@16: // dependencies so that build tools don't find them. Chris@16: // Chris@101: #define BOOST_REGEX_H1 Chris@101: #define BOOST_REGEX_H2 Chris@101: #define BOOST_REGEX_H3 Chris@101: #include BOOST_REGEX_H1 Chris@101: #include BOOST_REGEX_H2 Chris@101: #include BOOST_REGEX_H3 Chris@101: #undef BOOST_REGEX_H1 Chris@101: #undef BOOST_REGEX_H2 Chris@101: #undef BOOST_REGEX_H3 Chris@16: Chris@16: namespace boost{ Chris@16: Chris@16: class BOOST_REGEX_DECL scoped_static_mutex_lock; Chris@16: extern "C" BOOST_REGEX_DECL void boost_regex_free_static_mutex(); Chris@16: Chris@16: class BOOST_REGEX_DECL static_mutex Chris@16: { Chris@16: public: Chris@16: typedef scoped_static_mutex_lock scoped_lock; Chris@16: static void init(); Chris@16: static boost::recursive_mutex* m_pmutex; Chris@16: static boost::once_flag m_once; Chris@16: }; Chris@16: Chris@16: #define BOOST_STATIC_MUTEX_INIT { } Chris@16: Chris@16: class BOOST_REGEX_DECL scoped_static_mutex_lock Chris@16: { Chris@16: public: Chris@16: scoped_static_mutex_lock(static_mutex& mut, bool lk = true); Chris@16: ~scoped_static_mutex_lock(); Chris@16: operator void const*()const; Chris@16: bool locked()const; Chris@16: void lock(); Chris@16: void unlock(); Chris@16: private: Chris@101: boost::unique_lock* m_plock; Chris@16: bool m_have_lock; Chris@16: }; Chris@16: Chris@16: inline scoped_static_mutex_lock::operator void const*()const Chris@16: { Chris@16: return locked() ? this : 0; Chris@16: } Chris@16: Chris@16: inline bool scoped_static_mutex_lock::locked()const Chris@16: { Chris@16: return m_have_lock; Chris@16: } Chris@16: Chris@16: } // namespace Chris@16: Chris@16: #endif Chris@16: Chris@16: #endif