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