mirror of
https://github.com/boostorg/thread.git
synced 2026-02-08 23:22:13 +00:00
Merge from trunk
[SVN r39861]
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
// Copyright (C) 2001-2003
|
||||
// William E. Kempf
|
||||
// Copyright (C) 2007 Anthony Williams
|
||||
//
|
||||
// Distributed under 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)
|
||||
@@ -61,6 +62,7 @@ public:
|
||||
// still waiting to be removed from m_queue
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
pthread_cond_t m_condition;
|
||||
pthread_mutex_t m_mutex;
|
||||
#elif defined(BOOST_HAS_MPTASKS)
|
||||
MPSemaphoreID m_gate;
|
||||
MPSemaphoreID m_queue;
|
||||
@@ -90,7 +92,7 @@ public:
|
||||
if (!lock)
|
||||
throw lock_error();
|
||||
|
||||
do_wait(lock.m_mutex);
|
||||
do_wait(*lock.mutex());
|
||||
}
|
||||
|
||||
template <typename L, typename Pr>
|
||||
@@ -100,7 +102,7 @@ public:
|
||||
throw lock_error();
|
||||
|
||||
while (!pred())
|
||||
do_wait(lock.m_mutex);
|
||||
do_wait(*lock.mutex());
|
||||
}
|
||||
|
||||
template <typename L>
|
||||
@@ -109,7 +111,7 @@ public:
|
||||
if (!lock)
|
||||
throw lock_error();
|
||||
|
||||
return do_timed_wait(lock.m_mutex, xt);
|
||||
return do_timed_wait(*lock.mutex(), xt);
|
||||
}
|
||||
|
||||
template <typename L, typename Pr>
|
||||
@@ -120,7 +122,7 @@ public:
|
||||
|
||||
while (!pred())
|
||||
{
|
||||
if (!do_timed_wait(lock.m_mutex, xt))
|
||||
if (!do_timed_wait(*lock.mutex(), xt))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -135,25 +137,22 @@ private:
|
||||
{
|
||||
#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
|
||||
m_impl.enter_wait();
|
||||
#else
|
||||
pthread_mutex_lock(&m_impl.m_mutex);
|
||||
#endif
|
||||
|
||||
typedef detail::thread::lock_ops<M>
|
||||
#if defined(__HP_aCC) && __HP_aCC <= 33900 && !defined(BOOST_STRICT_CONFIG)
|
||||
# define lock_ops lock_ops_ // HP confuses lock_ops witht the template
|
||||
#endif
|
||||
lock_ops;
|
||||
|
||||
typename lock_ops::lock_state state;
|
||||
lock_ops::unlock(mutex, state);
|
||||
mutex.unlock();
|
||||
|
||||
#if defined(BOOST_HAS_PTHREADS)
|
||||
m_impl.do_wait(state.pmutex);
|
||||
m_impl.do_wait(&m_impl.m_mutex);
|
||||
#elif (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
|
||||
m_impl.do_wait();
|
||||
#endif
|
||||
|
||||
lock_ops::lock(mutex, state);
|
||||
#undef lock_ops
|
||||
#if defined(BOOST_HAS_PTHREADS)
|
||||
pthread_mutex_unlock(&m_impl.m_mutex);
|
||||
#endif
|
||||
mutex.lock();
|
||||
}
|
||||
|
||||
template <typename M>
|
||||
@@ -161,27 +160,24 @@ private:
|
||||
{
|
||||
#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
|
||||
m_impl.enter_wait();
|
||||
#else
|
||||
pthread_mutex_lock(&m_impl.m_mutex);
|
||||
#endif
|
||||
|
||||
typedef detail::thread::lock_ops<M>
|
||||
#if defined(__HP_aCC) && __HP_aCC <= 33900 && !defined(BOOST_STRICT_CONFIG)
|
||||
# define lock_ops lock_ops_ // HP confuses lock_ops witht the template
|
||||
#endif
|
||||
lock_ops;
|
||||
|
||||
typename lock_ops::lock_state state;
|
||||
lock_ops::unlock(mutex, state);
|
||||
mutex.unlock();
|
||||
|
||||
bool ret = false;
|
||||
|
||||
#if defined(BOOST_HAS_PTHREADS)
|
||||
ret = m_impl.do_timed_wait(xt, state.pmutex);
|
||||
ret = m_impl.do_timed_wait(xt, &m_impl.m_mutex);
|
||||
#elif (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
|
||||
ret = m_impl.do_timed_wait(xt);
|
||||
#endif
|
||||
|
||||
lock_ops::lock(mutex, state);
|
||||
#undef lock_ops
|
||||
#if defined(BOOST_HAS_PTHREADS)
|
||||
pthread_mutex_unlock(&m_impl.m_mutex);
|
||||
#endif
|
||||
mutex.lock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
486
include/boost/thread/locks.hpp
Normal file
486
include/boost/thread/locks.hpp
Normal file
@@ -0,0 +1,486 @@
|
||||
// Distributed under 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)
|
||||
// (C) Copyright 2007 Anthony Williams
|
||||
#ifndef BOOST_THREAD_LOCKS_HPP
|
||||
#define BOOST_THREAD_LOCKS_HPP
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
#include <algorithm>
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
struct defer_lock_t
|
||||
{};
|
||||
struct try_to_lock_t
|
||||
{};
|
||||
struct adopt_lock_t
|
||||
{};
|
||||
|
||||
const defer_lock_t defer_lock={};
|
||||
const try_to_lock_t try_to_lock={};
|
||||
const adopt_lock_t adopt_lock={};
|
||||
|
||||
template<typename Mutex>
|
||||
class shareable_lock;
|
||||
|
||||
template<typename Mutex>
|
||||
class exclusive_lock;
|
||||
|
||||
template<typename Mutex>
|
||||
class upgradeable_lock;
|
||||
|
||||
template<typename Mutex>
|
||||
class lock_guard
|
||||
{
|
||||
private:
|
||||
Mutex& m;
|
||||
|
||||
explicit lock_guard(lock_guard&);
|
||||
lock_guard& operator=(lock_guard&);
|
||||
public:
|
||||
explicit lock_guard(Mutex& m_):
|
||||
m(m_)
|
||||
{
|
||||
m.lock();
|
||||
}
|
||||
lock_guard(Mutex& m_,adopt_lock_t):
|
||||
m(m_)
|
||||
{}
|
||||
~lock_guard()
|
||||
{
|
||||
m.unlock();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Mutex>
|
||||
class unique_lock
|
||||
{
|
||||
private:
|
||||
Mutex* m;
|
||||
bool is_locked;
|
||||
explicit unique_lock(unique_lock&);
|
||||
unique_lock& operator=(unique_lock&);
|
||||
public:
|
||||
explicit unique_lock(Mutex& m_):
|
||||
m(&m_),is_locked(false)
|
||||
{
|
||||
lock();
|
||||
}
|
||||
unique_lock(Mutex& m_,adopt_lock_t):
|
||||
m(&m_),is_locked(true)
|
||||
{}
|
||||
unique_lock(Mutex& m_,defer_lock_t):
|
||||
m(&m_),is_locked(false)
|
||||
{}
|
||||
unique_lock(Mutex& m_,try_to_lock_t):
|
||||
m(&m_),is_locked(false)
|
||||
{
|
||||
try_lock();
|
||||
}
|
||||
unique_lock(Mutex& m_,system_time const& target_time):
|
||||
m(&m_),is_locked(false)
|
||||
{
|
||||
timed_lock(target_time);
|
||||
}
|
||||
unique_lock(boost::move_t<unique_lock> other):
|
||||
m(other->m),is_locked(other->is_locked)
|
||||
{
|
||||
other->is_locked=false;
|
||||
}
|
||||
unique_lock(boost::move_t<upgradeable_lock<Mutex> > other);
|
||||
|
||||
unique_lock& operator=(boost::move_t<unique_lock> other)
|
||||
{
|
||||
unique_lock temp(other);
|
||||
swap(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
unique_lock& operator=(boost::move_t<upgradeable_lock<Mutex> > other)
|
||||
{
|
||||
unique_lock temp(other);
|
||||
swap(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(unique_lock& other)
|
||||
{
|
||||
std::swap(m,other.m);
|
||||
std::swap(is_locked,other.is_locked);
|
||||
}
|
||||
void swap(boost::move_t<unique_lock> other)
|
||||
{
|
||||
std::swap(m,other->m);
|
||||
std::swap(is_locked,other->is_locked);
|
||||
}
|
||||
|
||||
~unique_lock()
|
||||
{
|
||||
if(owns_lock())
|
||||
{
|
||||
m->unlock();
|
||||
}
|
||||
}
|
||||
void lock()
|
||||
{
|
||||
if(owns_lock())
|
||||
{
|
||||
throw boost::lock_error();
|
||||
}
|
||||
m->lock();
|
||||
is_locked=true;
|
||||
}
|
||||
bool try_lock()
|
||||
{
|
||||
if(owns_lock())
|
||||
{
|
||||
throw boost::lock_error();
|
||||
}
|
||||
is_locked=m->try_lock();
|
||||
return is_locked;
|
||||
}
|
||||
template<typename TimeDuration>
|
||||
bool timed_lock(TimeDuration const& relative_time)
|
||||
{
|
||||
is_locked=m->timed_lock(relative_time);
|
||||
return is_locked;
|
||||
}
|
||||
|
||||
bool timed_lock(::boost::system_time const& absolute_time)
|
||||
{
|
||||
is_locked=m->timed_lock(absolute_time);
|
||||
return is_locked;
|
||||
}
|
||||
void unlock()
|
||||
{
|
||||
if(!owns_lock())
|
||||
{
|
||||
throw boost::lock_error();
|
||||
}
|
||||
m->unlock();
|
||||
is_locked=false;
|
||||
}
|
||||
|
||||
typedef void (unique_lock::*bool_type)();
|
||||
operator bool_type() const
|
||||
{
|
||||
return is_locked?&unique_lock::lock:0;
|
||||
}
|
||||
bool owns_lock() const
|
||||
{
|
||||
return is_locked;
|
||||
}
|
||||
|
||||
Mutex* mutex() const
|
||||
{
|
||||
return m;
|
||||
}
|
||||
|
||||
Mutex* release()
|
||||
{
|
||||
Mutex* const res=m;
|
||||
m=0;
|
||||
is_locked=false;
|
||||
return res;
|
||||
}
|
||||
|
||||
friend class shareable_lock<Mutex>;
|
||||
friend class upgradeable_lock<Mutex>;
|
||||
};
|
||||
|
||||
template<typename Mutex>
|
||||
class shareable_lock
|
||||
{
|
||||
protected:
|
||||
Mutex* m;
|
||||
bool is_locked;
|
||||
private:
|
||||
explicit shareable_lock(shareable_lock&);
|
||||
shareable_lock& operator=(shareable_lock&);
|
||||
public:
|
||||
explicit shareable_lock(Mutex& m_):
|
||||
m(&m_),is_locked(false)
|
||||
{
|
||||
lock();
|
||||
}
|
||||
shareable_lock(Mutex& m_,bool do_lock):
|
||||
m(&m_),is_locked(false)
|
||||
{
|
||||
if(do_lock)
|
||||
{
|
||||
lock();
|
||||
}
|
||||
}
|
||||
shareable_lock(boost::move_t<shareable_lock> other):
|
||||
m(other->m),is_locked(other->is_locked)
|
||||
{
|
||||
other->is_locked=false;
|
||||
}
|
||||
|
||||
shareable_lock(boost::move_t<unique_lock<Mutex> > other):
|
||||
m(other->m),is_locked(other->is_locked)
|
||||
{
|
||||
other->is_locked=false;
|
||||
if(is_locked)
|
||||
{
|
||||
m->unlock_and_lock_shareable();
|
||||
}
|
||||
}
|
||||
|
||||
shareable_lock(boost::move_t<upgradeable_lock<Mutex> > other):
|
||||
m(other->m),is_locked(other->is_locked)
|
||||
{
|
||||
other->is_locked=false;
|
||||
if(is_locked)
|
||||
{
|
||||
m->unlock_upgradeable_and_lock_shareable();
|
||||
}
|
||||
}
|
||||
|
||||
shareable_lock& operator=(boost::move_t<shareable_lock> other)
|
||||
{
|
||||
shareable_lock temp(other);
|
||||
swap(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
shareable_lock& operator=(boost::move_t<unique_lock<Mutex> > other)
|
||||
{
|
||||
shareable_lock temp(other);
|
||||
swap(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
shareable_lock& operator=(boost::move_t<upgradeable_lock<Mutex> > other)
|
||||
{
|
||||
shareable_lock temp(other);
|
||||
swap(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(shareable_lock& other)
|
||||
{
|
||||
std::swap(m,other.m);
|
||||
std::swap(is_locked,other.is_locked);
|
||||
}
|
||||
|
||||
~shareable_lock()
|
||||
{
|
||||
if(owns_lock())
|
||||
{
|
||||
m->unlock_shareable();
|
||||
}
|
||||
}
|
||||
void lock()
|
||||
{
|
||||
if(owns_lock())
|
||||
{
|
||||
throw boost::lock_error();
|
||||
}
|
||||
m->lock_shareable();
|
||||
is_locked=true;
|
||||
}
|
||||
bool try_lock()
|
||||
{
|
||||
if(owns_lock())
|
||||
{
|
||||
throw boost::lock_error();
|
||||
}
|
||||
is_locked=m->try_lock_shareable();
|
||||
return is_locked;
|
||||
}
|
||||
void unlock()
|
||||
{
|
||||
if(!owns_lock())
|
||||
{
|
||||
throw boost::lock_error();
|
||||
}
|
||||
m->unlock_shareable();
|
||||
is_locked=false;
|
||||
}
|
||||
|
||||
typedef void (shareable_lock::*bool_type)();
|
||||
operator bool_type() const
|
||||
{
|
||||
return is_locked?&shareable_lock::lock:0;
|
||||
}
|
||||
bool owns_lock() const
|
||||
{
|
||||
return is_locked;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename Mutex>
|
||||
class upgradeable_lock
|
||||
{
|
||||
protected:
|
||||
Mutex* m;
|
||||
bool is_locked;
|
||||
private:
|
||||
explicit upgradeable_lock(upgradeable_lock&);
|
||||
upgradeable_lock& operator=(upgradeable_lock&);
|
||||
public:
|
||||
explicit upgradeable_lock(Mutex& m_):
|
||||
m(&m_),is_locked(false)
|
||||
{
|
||||
lock();
|
||||
}
|
||||
upgradeable_lock(Mutex& m_,bool do_lock):
|
||||
m(&m_),is_locked(false)
|
||||
{
|
||||
if(do_lock)
|
||||
{
|
||||
lock();
|
||||
}
|
||||
}
|
||||
upgradeable_lock(boost::move_t<upgradeable_lock> other):
|
||||
m(other->m),is_locked(other->is_locked)
|
||||
{
|
||||
other->is_locked=false;
|
||||
}
|
||||
|
||||
upgradeable_lock(boost::move_t<unique_lock<Mutex> > other):
|
||||
m(other->m),is_locked(other->is_locked)
|
||||
{
|
||||
other->is_locked=false;
|
||||
if(is_locked)
|
||||
{
|
||||
m->unlock_and_lock_upgradeable();
|
||||
}
|
||||
}
|
||||
|
||||
upgradeable_lock& operator=(boost::move_t<upgradeable_lock> other)
|
||||
{
|
||||
upgradeable_lock temp(other);
|
||||
swap(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
upgradeable_lock& operator=(boost::move_t<unique_lock<Mutex> > other)
|
||||
{
|
||||
upgradeable_lock temp(other);
|
||||
swap(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(upgradeable_lock& other)
|
||||
{
|
||||
std::swap(m,other.m);
|
||||
std::swap(is_locked,other.is_locked);
|
||||
}
|
||||
|
||||
~upgradeable_lock()
|
||||
{
|
||||
if(owns_lock())
|
||||
{
|
||||
m->unlock_upgradeable();
|
||||
}
|
||||
}
|
||||
void lock()
|
||||
{
|
||||
if(owns_lock())
|
||||
{
|
||||
throw boost::lock_error();
|
||||
}
|
||||
m->lock_upgradeable();
|
||||
is_locked=true;
|
||||
}
|
||||
bool try_lock()
|
||||
{
|
||||
if(owns_lock())
|
||||
{
|
||||
throw boost::lock_error();
|
||||
}
|
||||
is_locked=m->try_lock_upgradeable();
|
||||
return is_locked;
|
||||
}
|
||||
void unlock()
|
||||
{
|
||||
if(!owns_lock())
|
||||
{
|
||||
throw boost::lock_error();
|
||||
}
|
||||
m->unlock_upgradeable();
|
||||
is_locked=false;
|
||||
}
|
||||
|
||||
typedef void (upgradeable_lock::*bool_type)();
|
||||
operator bool_type() const
|
||||
{
|
||||
return is_locked?&upgradeable_lock::lock:0;
|
||||
}
|
||||
bool owns_lock() const
|
||||
{
|
||||
return is_locked;
|
||||
}
|
||||
friend class shareable_lock<Mutex>;
|
||||
friend class unique_lock<Mutex>;
|
||||
};
|
||||
|
||||
template<typename Mutex>
|
||||
unique_lock<Mutex>::unique_lock(boost::move_t<upgradeable_lock<Mutex> > other):
|
||||
m(other->m),is_locked(other->is_locked)
|
||||
{
|
||||
other->is_locked=false;
|
||||
if(is_locked)
|
||||
{
|
||||
m->unlock_upgradeable_and_lock();
|
||||
}
|
||||
}
|
||||
|
||||
template <class Mutex>
|
||||
class upgrade_to_unique_lock
|
||||
{
|
||||
private:
|
||||
upgradeable_lock<Mutex>* source;
|
||||
unique_lock<Mutex> exclusive;
|
||||
|
||||
explicit upgrade_to_unique_lock(upgrade_to_unique_lock&);
|
||||
upgrade_to_unique_lock& operator=(upgrade_to_unique_lock&);
|
||||
public:
|
||||
explicit upgrade_to_unique_lock(upgradeable_lock<Mutex>& m_):
|
||||
source(&m_),exclusive(boost::move(*source))
|
||||
{}
|
||||
~upgrade_to_unique_lock()
|
||||
{
|
||||
if(source)
|
||||
{
|
||||
*source=boost::move(exclusive);
|
||||
}
|
||||
}
|
||||
|
||||
upgrade_to_unique_lock(boost::move_t<upgrade_to_unique_lock> other):
|
||||
source(other->source),exclusive(boost::move(other->exclusive))
|
||||
{
|
||||
other->source=0;
|
||||
}
|
||||
|
||||
upgrade_to_unique_lock& operator=(boost::move_t<upgrade_to_unique_lock> other)
|
||||
{
|
||||
upgrade_to_unique_lock temp(other);
|
||||
swap(temp);
|
||||
return *this;
|
||||
}
|
||||
void swap(upgrade_to_unique_lock& other)
|
||||
{
|
||||
std::swap(source,other.source);
|
||||
exclusive.swap(other.exclusive);
|
||||
}
|
||||
typedef void (upgrade_to_unique_lock::*bool_type)(upgrade_to_unique_lock&);
|
||||
operator bool_type() const
|
||||
{
|
||||
return exclusive.owns_lock()?&upgrade_to_unique_lock::swap:0;
|
||||
}
|
||||
bool owns_lock() const
|
||||
{
|
||||
return exclusive.owns_lock();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,170 +1,15 @@
|
||||
// Copyright (C) 2001-2003
|
||||
// William E. Kempf
|
||||
#ifndef BOOST_THREAD_MUTEX_HPP
|
||||
#define BOOST_THREAD_MUTEX_HPP
|
||||
|
||||
// mutex.hpp
|
||||
//
|
||||
// Distributed under 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)
|
||||
// (C) Copyright 2007 Anthony Williams
|
||||
//
|
||||
// Distributed under 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)
|
||||
|
||||
#ifndef BOOST_MUTEX_WEK070601_HPP
|
||||
#define BOOST_MUTEX_WEK070601_HPP
|
||||
#include <boost/thread/detail/platform.hpp>
|
||||
#include BOOST_THREAD_PLATFORM(mutex.hpp)
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/thread/detail/lock.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_PTHREADS)
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_MPTASKS)
|
||||
# include "scoped_critical_region.hpp"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
struct xtime;
|
||||
// disable warnings about non dll import
|
||||
// see: http://www.boost.org/more/separate_compilation.html#dlls
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4251 4231 4660 4275)
|
||||
#endif
|
||||
|
||||
class BOOST_THREAD_DECL mutex
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
friend class detail::thread::lock_ops<mutex>;
|
||||
|
||||
typedef detail::thread::scoped_lock<mutex> scoped_lock;
|
||||
|
||||
mutex();
|
||||
~mutex();
|
||||
|
||||
private:
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
typedef void* cv_state;
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
struct cv_state
|
||||
{
|
||||
pthread_mutex_t* pmutex;
|
||||
};
|
||||
#elif defined(BOOST_HAS_MPTASKS)
|
||||
struct cv_state
|
||||
{
|
||||
};
|
||||
#endif
|
||||
void do_lock();
|
||||
void do_unlock();
|
||||
void do_lock(cv_state& state);
|
||||
void do_unlock(cv_state& state);
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
void* m_mutex;
|
||||
bool m_critical_section;
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
pthread_mutex_t m_mutex;
|
||||
#elif defined(BOOST_HAS_MPTASKS)
|
||||
threads::mac::detail::scoped_critical_region m_mutex;
|
||||
threads::mac::detail::scoped_critical_region m_mutex_mutex;
|
||||
#endif
|
||||
};
|
||||
|
||||
class BOOST_THREAD_DECL try_mutex
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
friend class detail::thread::lock_ops<try_mutex>;
|
||||
|
||||
typedef detail::thread::scoped_lock<try_mutex> scoped_lock;
|
||||
typedef detail::thread::scoped_try_lock<try_mutex> scoped_try_lock;
|
||||
|
||||
try_mutex();
|
||||
~try_mutex();
|
||||
|
||||
private:
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
typedef void* cv_state;
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
struct cv_state
|
||||
{
|
||||
pthread_mutex_t* pmutex;
|
||||
};
|
||||
#elif defined(BOOST_HAS_MPTASKS)
|
||||
struct cv_state
|
||||
{
|
||||
};
|
||||
#endif
|
||||
void do_lock();
|
||||
bool do_trylock();
|
||||
void do_unlock();
|
||||
void do_lock(cv_state& state);
|
||||
void do_unlock(cv_state& state);
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
void* m_mutex;
|
||||
bool m_critical_section;
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
pthread_mutex_t m_mutex;
|
||||
#elif defined(BOOST_HAS_MPTASKS)
|
||||
threads::mac::detail::scoped_critical_region m_mutex;
|
||||
threads::mac::detail::scoped_critical_region m_mutex_mutex;
|
||||
#endif
|
||||
};
|
||||
|
||||
class BOOST_THREAD_DECL timed_mutex
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
friend class detail::thread::lock_ops<timed_mutex>;
|
||||
|
||||
typedef detail::thread::scoped_lock<timed_mutex> scoped_lock;
|
||||
typedef detail::thread::scoped_try_lock<timed_mutex> scoped_try_lock;
|
||||
typedef detail::thread::scoped_timed_lock<timed_mutex> scoped_timed_lock;
|
||||
|
||||
timed_mutex();
|
||||
~timed_mutex();
|
||||
|
||||
private:
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
typedef void* cv_state;
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
struct cv_state
|
||||
{
|
||||
pthread_mutex_t* pmutex;
|
||||
};
|
||||
#elif defined(BOOST_HAS_MPTASKS)
|
||||
struct cv_state
|
||||
{
|
||||
};
|
||||
#endif
|
||||
void do_lock();
|
||||
bool do_trylock();
|
||||
bool do_timedlock(const xtime& xt);
|
||||
void do_unlock();
|
||||
void do_lock(cv_state& state);
|
||||
void do_unlock(cv_state& state);
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
void* m_mutex;
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
pthread_mutex_t m_mutex;
|
||||
pthread_cond_t m_condition;
|
||||
bool m_locked;
|
||||
#elif defined(BOOST_HAS_MPTASKS)
|
||||
threads::mac::detail::scoped_critical_region m_mutex;
|
||||
threads::mac::detail::scoped_critical_region m_mutex_mutex;
|
||||
#endif
|
||||
};
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
} // namespace boost
|
||||
|
||||
// Change Log:
|
||||
// 8 Feb 01 WEKEMPF Initial version.
|
||||
// 22 May 01 WEKEMPF Modified to use xtime for time outs. Factored out
|
||||
// to three classes, mutex, try_mutex and timed_mutex.
|
||||
// 3 Jan 03 WEKEMPF Modified for DLL implementation.
|
||||
|
||||
#endif // BOOST_MUTEX_WEK070601_HPP
|
||||
|
||||
@@ -10,19 +10,14 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/thread/detail/platform.hpp>
|
||||
#ifdef BOOST_HAS_MPTASKS
|
||||
namespace boost {
|
||||
|
||||
typedef long once_flag;
|
||||
#define BOOST_ONCE_INIT 0
|
||||
|
||||
void call_once(once_flag& flag, void (*func)());
|
||||
#include BOOST_THREAD_PLATFORM(once.hpp)
|
||||
|
||||
namespace boost
|
||||
{
|
||||
inline void call_once(void (*func)(),once_flag& flag)
|
||||
{
|
||||
call_once(flag,func);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#include BOOST_THREAD_PLATFORM(once.hpp)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
216
include/boost/thread/pthread/mutex.hpp
Normal file
216
include/boost/thread/pthread/mutex.hpp
Normal file
@@ -0,0 +1,216 @@
|
||||
#ifndef BOOST_THREAD_PTHREAD_MUTEX_HPP
|
||||
#define BOOST_THREAD_PTHREAD_MUTEX_HPP
|
||||
// (C) Copyright 2007 Anthony Williams
|
||||
// Distributed under 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)
|
||||
|
||||
#include <pthread.h>
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
#include <boost/thread/locks.hpp>
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "timespec.hpp"
|
||||
|
||||
#ifdef _POSIX_TIMEOUTS
|
||||
#if _POSIX_TIMEOUTS >= 0
|
||||
#define BOOST_PTHREAD_HAS_TIMEDLOCK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
class mutex:
|
||||
boost::noncopyable
|
||||
{
|
||||
private:
|
||||
pthread_mutex_t m;
|
||||
public:
|
||||
mutex()
|
||||
{
|
||||
int const res=pthread_mutex_init(&m,NULL);
|
||||
if(res)
|
||||
{
|
||||
throw thread_resource_error();
|
||||
}
|
||||
}
|
||||
~mutex()
|
||||
{
|
||||
int const res=pthread_mutex_destroy(&m);
|
||||
BOOST_ASSERT(!res);
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
int const res=pthread_mutex_lock(&m);
|
||||
BOOST_ASSERT(!res);
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
int const res=pthread_mutex_unlock(&m);
|
||||
BOOST_ASSERT(!res);
|
||||
}
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
int const res=pthread_mutex_trylock(&m);
|
||||
BOOST_ASSERT(!res || res==EBUSY);
|
||||
return !res;
|
||||
}
|
||||
typedef unique_lock<mutex> scoped_lock;
|
||||
typedef scoped_lock scoped_try_lock;
|
||||
};
|
||||
|
||||
typedef mutex try_mutex;
|
||||
|
||||
class timed_mutex:
|
||||
boost::noncopyable
|
||||
{
|
||||
private:
|
||||
pthread_mutex_t m;
|
||||
#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
|
||||
pthread_cond_t cond;
|
||||
bool is_locked;
|
||||
|
||||
struct pthread_mutex_scoped_lock
|
||||
{
|
||||
pthread_mutex_t* m;
|
||||
explicit pthread_mutex_scoped_lock(pthread_mutex_t* m_):
|
||||
m(m_)
|
||||
{
|
||||
int const res=pthread_mutex_lock(m);
|
||||
BOOST_ASSERT(!res);
|
||||
}
|
||||
~pthread_mutex_scoped_lock()
|
||||
{
|
||||
int const res=pthread_mutex_unlock(m);
|
||||
BOOST_ASSERT(!res);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
public:
|
||||
timed_mutex()
|
||||
{
|
||||
int const res=pthread_mutex_init(&m,NULL);
|
||||
if(res)
|
||||
{
|
||||
throw thread_resource_error();
|
||||
}
|
||||
#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
|
||||
int const res2=pthread_cond_init(&cond,NULL);
|
||||
if(res2)
|
||||
{
|
||||
int const destroy_res=pthread_mutex_destroy(&m);
|
||||
BOOST_ASSERT(!destroy_res);
|
||||
throw thread_resource_error();
|
||||
}
|
||||
is_locked=false;
|
||||
#endif
|
||||
}
|
||||
~timed_mutex()
|
||||
{
|
||||
int const res=pthread_mutex_destroy(&m);
|
||||
BOOST_ASSERT(!res);
|
||||
#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
|
||||
int const res2=pthread_cond_destroy(&cond);
|
||||
BOOST_ASSERT(!res2);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename TimeDuration>
|
||||
bool timed_lock(TimeDuration const & relative_time)
|
||||
{
|
||||
return timed_lock(get_system_time()+relative_time);
|
||||
}
|
||||
|
||||
#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
|
||||
void lock()
|
||||
{
|
||||
int const res=pthread_mutex_lock(&m);
|
||||
BOOST_ASSERT(!res);
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
int const res=pthread_mutex_unlock(&m);
|
||||
BOOST_ASSERT(!res);
|
||||
}
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
int const res=pthread_mutex_trylock(&m);
|
||||
BOOST_ASSERT(!res || res==EBUSY);
|
||||
return !res;
|
||||
}
|
||||
bool timed_lock(system_time const & abs_time)
|
||||
{
|
||||
struct timespec const timeout=detail::get_timespec(abs_time);
|
||||
int const res=pthread_mutex_timedlock(&m,&timeout);
|
||||
BOOST_ASSERT(!res || res==EBUSY);
|
||||
return !res;
|
||||
}
|
||||
#else
|
||||
void lock()
|
||||
{
|
||||
pthread_mutex_scoped_lock const _(&m);
|
||||
while(is_locked)
|
||||
{
|
||||
int const cond_res=pthread_cond_wait(&cond,&m);
|
||||
BOOST_ASSERT(!cond_res);
|
||||
}
|
||||
is_locked=true;
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
pthread_mutex_scoped_lock const _(&m);
|
||||
is_locked=false;
|
||||
int const res=pthread_cond_signal(&cond);
|
||||
BOOST_ASSERT(!res);
|
||||
}
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
pthread_mutex_scoped_lock const _(&m);
|
||||
if(is_locked)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
is_locked=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool timed_lock(system_time const & abs_time)
|
||||
{
|
||||
struct timespec const timeout=detail::get_timespec(abs_time);
|
||||
pthread_mutex_scoped_lock const _(&m);
|
||||
while(is_locked)
|
||||
{
|
||||
int const cond_res=pthread_cond_timewait(&cond,&m,&timeout);
|
||||
if(cond_res==ETIMEOUT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
BOOST_ASSERT(!cond_res);
|
||||
}
|
||||
is_locked=true;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef unique_lock<timed_mutex> scoped_timed_lock;
|
||||
typedef scoped_timed_lock scoped_try_lock;
|
||||
typedef scoped_timed_lock scoped_lock;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
276
include/boost/thread/pthread/recursive_mutex.hpp
Normal file
276
include/boost/thread/pthread/recursive_mutex.hpp
Normal file
@@ -0,0 +1,276 @@
|
||||
#ifndef BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP
|
||||
#define BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP
|
||||
// (C) Copyright 2007 Anthony Williams
|
||||
// Distributed under 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)
|
||||
|
||||
#include <pthread.h>
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
#include <boost/thread/locks.hpp>
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <unistd.h>
|
||||
#include <boost/date_time/posix_time/conversion.hpp>
|
||||
#include <errno.h>
|
||||
#include "timespec.hpp"
|
||||
|
||||
#ifdef _POSIX_TIMEOUTS
|
||||
#if _POSIX_TIMEOUTS >= 0
|
||||
#define BOOST_PTHREAD_HAS_TIMEDLOCK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
class recursive_mutex:
|
||||
boost::noncopyable
|
||||
{
|
||||
private:
|
||||
pthread_mutex_t m;
|
||||
public:
|
||||
recursive_mutex()
|
||||
{
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
int const init_attr_res=pthread_mutexattr_init(&attr);
|
||||
if(init_attr_res)
|
||||
{
|
||||
throw thread_resource_error();
|
||||
}
|
||||
int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
|
||||
if(set_attr_res)
|
||||
{
|
||||
throw thread_resource_error();
|
||||
}
|
||||
|
||||
int const res=pthread_mutex_init(&m,&attr);
|
||||
if(res)
|
||||
{
|
||||
throw thread_resource_error();
|
||||
}
|
||||
int const destroy_attr_res=pthread_mutexattr_destroy(&attr);
|
||||
BOOST_ASSERT(!destroy_attr_res);
|
||||
}
|
||||
~recursive_mutex()
|
||||
{
|
||||
int const res=pthread_mutex_destroy(&m);
|
||||
BOOST_ASSERT(!res);
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
int const res=pthread_mutex_lock(&m);
|
||||
BOOST_ASSERT(!res);
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
int const res=pthread_mutex_unlock(&m);
|
||||
BOOST_ASSERT(!res);
|
||||
}
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
int const res=pthread_mutex_trylock(&m);
|
||||
BOOST_ASSERT(!res || res==EBUSY);
|
||||
return !res;
|
||||
}
|
||||
typedef unique_lock<recursive_mutex> scoped_lock;
|
||||
typedef scoped_lock scoped_try_lock;
|
||||
};
|
||||
|
||||
typedef recursive_mutex recursive_try_mutex;
|
||||
|
||||
class recursive_timed_mutex:
|
||||
boost::noncopyable
|
||||
{
|
||||
private:
|
||||
pthread_mutex_t m;
|
||||
#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
|
||||
pthread_cond_t cond;
|
||||
bool is_locked;
|
||||
pthread_t owner;
|
||||
unsigned count;
|
||||
|
||||
struct pthread_mutex_scoped_lock
|
||||
{
|
||||
pthread_mutex_t* m;
|
||||
explicit pthread_mutex_scoped_lock(pthread_mutex_t* m_):
|
||||
m(m_)
|
||||
{
|
||||
int const res=pthread_mutex_lock(m);
|
||||
BOOST_ASSERT(!res);
|
||||
}
|
||||
~pthread_mutex_scoped_lock()
|
||||
{
|
||||
int const res=pthread_mutex_unlock(m);
|
||||
BOOST_ASSERT(!res);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
public:
|
||||
recursive_timed_mutex()
|
||||
{
|
||||
#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
int const init_attr_res=pthread_mutexattr_init(&attr);
|
||||
if(init_attr_res)
|
||||
{
|
||||
throw thread_resource_error();
|
||||
}
|
||||
int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
|
||||
if(set_attr_res)
|
||||
{
|
||||
throw thread_resource_error();
|
||||
}
|
||||
|
||||
int const res=pthread_mutex_init(&m,&attr);
|
||||
if(res)
|
||||
{
|
||||
throw thread_resource_error();
|
||||
}
|
||||
int const destroy_attr_res=pthread_mutexattr_destroy(&attr);
|
||||
BOOST_ASSERT(!destroy_attr_res);
|
||||
#else
|
||||
int const res=pthread_mutex_init(&m,NULL);
|
||||
if(res)
|
||||
{
|
||||
throw thread_resource_error();
|
||||
}
|
||||
int const res2=pthread_cond_init(&cond,NULL);
|
||||
if(res2)
|
||||
{
|
||||
int const destroy_res=pthread_mutex_destroy(&m);
|
||||
BOOST_ASSERT(!destroy_res);
|
||||
throw thread_resource_error();
|
||||
}
|
||||
is_locked=false;
|
||||
count=0;
|
||||
#endif
|
||||
}
|
||||
~recursive_timed_mutex()
|
||||
{
|
||||
int const res=pthread_mutex_destroy(&m);
|
||||
BOOST_ASSERT(!res);
|
||||
#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
|
||||
int const res2=pthread_cond_destroy(&cond);
|
||||
BOOST_ASSERT(!res2);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename TimeDuration>
|
||||
bool timed_lock(TimeDuration const & relative_time)
|
||||
{
|
||||
return timed_lock(get_system_time()+relative_time);
|
||||
}
|
||||
|
||||
#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
|
||||
void lock()
|
||||
{
|
||||
int const res=pthread_mutex_lock(&m);
|
||||
BOOST_ASSERT(!res);
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
int const res=pthread_mutex_unlock(&m);
|
||||
BOOST_ASSERT(!res);
|
||||
}
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
int const res=pthread_mutex_trylock(&m);
|
||||
BOOST_ASSERT(!res || res==EBUSY);
|
||||
return !res;
|
||||
}
|
||||
bool timed_lock(system_time const & abs_time)
|
||||
{
|
||||
struct timespec const timeout=detail::get_timespec(abs_time);
|
||||
int const res=pthread_mutex_timedlock(&m,&timeout);
|
||||
BOOST_ASSERT(!res || res==EBUSY);
|
||||
return !res;
|
||||
}
|
||||
#else
|
||||
void lock()
|
||||
{
|
||||
pthread_mutex_scoped_lock const _(&m);
|
||||
if(is_locked && owner==pthread_self())
|
||||
{
|
||||
++count;
|
||||
return;
|
||||
}
|
||||
|
||||
while(is_locked)
|
||||
{
|
||||
int const cond_res=pthread_cond_wait(&cond,&m);
|
||||
BOOST_ASSERT(!cond_res);
|
||||
}
|
||||
is_locked=true;
|
||||
++count;
|
||||
owner=pthread_self();
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
pthread_mutex_scoped_lock const _(&m);
|
||||
if(!--count)
|
||||
{
|
||||
is_locked=false;
|
||||
}
|
||||
int const res=pthread_cond_signal(&cond);
|
||||
BOOST_ASSERT(!res);
|
||||
}
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
pthread_mutex_scoped_lock const _(&m);
|
||||
if(is_locked && owner!=pthread_self())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
is_locked=true;
|
||||
++count;
|
||||
owner=pthread_self();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool timed_lock(system_time const & abs_time)
|
||||
{
|
||||
struct timespec const timeout=detail::get_timespec(abs_time);
|
||||
pthread_mutex_scoped_lock const _(&m);
|
||||
if(is_locked && owner==pthread_self())
|
||||
{
|
||||
++count;
|
||||
return;
|
||||
}
|
||||
while(is_locked)
|
||||
{
|
||||
int const cond_res=pthread_cond_timewait(&cond,&m,&timeout);
|
||||
if(cond_res==ETIMEOUT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
BOOST_ASSERT(!cond_res);
|
||||
}
|
||||
is_locked=true;
|
||||
++count;
|
||||
owner=pthread_self();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef unique_lock<recursive_timed_mutex> scoped_timed_lock;
|
||||
typedef scoped_timed_lock scoped_try_lock;
|
||||
typedef scoped_timed_lock scoped_lock;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
23
include/boost/thread/pthread/timespec.hpp
Normal file
23
include/boost/thread/pthread/timespec.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef BOOST_THREAD_PTHREAD_TIMESPEC_HPP
|
||||
#define BOOST_THREAD_PTHREAD_TIMESPEC_HPP
|
||||
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
#include <boost/date_time/posix_time/conversion.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
inline struct timespec get_timespec(boost::system_time const& abs_time)
|
||||
{
|
||||
struct timespec timeout={0};
|
||||
boost::posix_time::time_duration const time_since_epoch=abs_time-boost::posix_time::from_time_t(0);
|
||||
|
||||
timeout.tv_sec=time_since_epoch.total_seconds();
|
||||
timeout.tv_nsec=time_since_epoch.fractional_seconds()*(1000000000/time_since_epoch.ticks_per_second());
|
||||
return timeout;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,184 +1,15 @@
|
||||
// Copyright (C) 2001-2003
|
||||
// William E. Kempf
|
||||
#ifndef BOOST_THREAD_RECURSIVE_MUTEX_HPP
|
||||
#define BOOST_THREAD_RECURSIVE_MUTEX_HPP
|
||||
|
||||
// recursive_mutex.hpp
|
||||
//
|
||||
// Distributed under 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)
|
||||
// (C) Copyright 2007 Anthony Williams
|
||||
//
|
||||
// Distributed under 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)
|
||||
|
||||
#ifndef BOOST_RECURSIVE_MUTEX_WEK070601_HPP
|
||||
#define BOOST_RECURSIVE_MUTEX_WEK070601_HPP
|
||||
#include <boost/thread/detail/platform.hpp>
|
||||
#include BOOST_THREAD_PLATFORM(recursive_mutex.hpp)
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/thread/detail/lock.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_PTHREADS)
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_MPTASKS)
|
||||
# include "scoped_critical_region.hpp"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
struct xtime;
|
||||
// disable warnings about non dll import
|
||||
// see: http://www.boost.org/more/separate_compilation.html#dlls
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4251 4231 4660 4275)
|
||||
#endif
|
||||
class BOOST_THREAD_DECL recursive_mutex
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
friend class detail::thread::lock_ops<recursive_mutex>;
|
||||
|
||||
typedef detail::thread::scoped_lock<recursive_mutex> scoped_lock;
|
||||
|
||||
recursive_mutex();
|
||||
~recursive_mutex();
|
||||
|
||||
private:
|
||||
#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
|
||||
typedef std::size_t cv_state;
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
struct cv_state
|
||||
{
|
||||
long count;
|
||||
pthread_mutex_t* pmutex;
|
||||
};
|
||||
#endif
|
||||
void do_lock();
|
||||
void do_unlock();
|
||||
void do_lock(cv_state& state);
|
||||
void do_unlock(cv_state& state);
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
void* m_mutex;
|
||||
bool m_critical_section;
|
||||
unsigned long m_count;
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
pthread_mutex_t m_mutex;
|
||||
unsigned m_count;
|
||||
# if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
|
||||
pthread_cond_t m_unlocked;
|
||||
pthread_t m_thread_id;
|
||||
bool m_valid_id;
|
||||
# endif
|
||||
#elif defined(BOOST_HAS_MPTASKS)
|
||||
threads::mac::detail::scoped_critical_region m_mutex;
|
||||
threads::mac::detail::scoped_critical_region m_mutex_mutex;
|
||||
std::size_t m_count;
|
||||
#endif
|
||||
};
|
||||
|
||||
class BOOST_THREAD_DECL recursive_try_mutex
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
friend class detail::thread::lock_ops<recursive_try_mutex>;
|
||||
|
||||
typedef detail::thread::scoped_lock<recursive_try_mutex> scoped_lock;
|
||||
typedef detail::thread::scoped_try_lock<
|
||||
recursive_try_mutex> scoped_try_lock;
|
||||
|
||||
recursive_try_mutex();
|
||||
~recursive_try_mutex();
|
||||
|
||||
private:
|
||||
#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
|
||||
typedef std::size_t cv_state;
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
struct cv_state
|
||||
{
|
||||
long count;
|
||||
pthread_mutex_t* pmutex;
|
||||
};
|
||||
#endif
|
||||
void do_lock();
|
||||
bool do_trylock();
|
||||
void do_unlock();
|
||||
void do_lock(cv_state& state);
|
||||
void do_unlock(cv_state& state);
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
void* m_mutex;
|
||||
bool m_critical_section;
|
||||
unsigned long m_count;
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
pthread_mutex_t m_mutex;
|
||||
unsigned m_count;
|
||||
# if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
|
||||
pthread_cond_t m_unlocked;
|
||||
pthread_t m_thread_id;
|
||||
bool m_valid_id;
|
||||
# endif
|
||||
#elif defined(BOOST_HAS_MPTASKS)
|
||||
threads::mac::detail::scoped_critical_region m_mutex;
|
||||
threads::mac::detail::scoped_critical_region m_mutex_mutex;
|
||||
std::size_t m_count;
|
||||
#endif
|
||||
};
|
||||
|
||||
class BOOST_THREAD_DECL recursive_timed_mutex
|
||||
: private noncopyable
|
||||
{
|
||||
public:
|
||||
friend class detail::thread::lock_ops<recursive_timed_mutex>;
|
||||
|
||||
typedef detail::thread::scoped_lock<recursive_timed_mutex> scoped_lock;
|
||||
typedef detail::thread::scoped_try_lock<
|
||||
recursive_timed_mutex> scoped_try_lock;
|
||||
typedef detail::thread::scoped_timed_lock<
|
||||
recursive_timed_mutex> scoped_timed_lock;
|
||||
|
||||
recursive_timed_mutex();
|
||||
~recursive_timed_mutex();
|
||||
|
||||
private:
|
||||
#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
|
||||
typedef std::size_t cv_state;
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
struct cv_state
|
||||
{
|
||||
long count;
|
||||
pthread_mutex_t* pmutex;
|
||||
};
|
||||
#endif
|
||||
void do_lock();
|
||||
bool do_trylock();
|
||||
bool do_timedlock(const xtime& xt);
|
||||
void do_unlock();
|
||||
void do_lock(cv_state& state);
|
||||
void do_unlock(cv_state& state);
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS)
|
||||
void* m_mutex;
|
||||
unsigned long m_count;
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
pthread_mutex_t m_mutex;
|
||||
pthread_cond_t m_unlocked;
|
||||
pthread_t m_thread_id;
|
||||
bool m_valid_id;
|
||||
unsigned m_count;
|
||||
#elif defined(BOOST_HAS_MPTASKS)
|
||||
threads::mac::detail::scoped_critical_region m_mutex;
|
||||
threads::mac::detail::scoped_critical_region m_mutex_mutex;
|
||||
std::size_t m_count;
|
||||
#endif
|
||||
};
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_RECURSIVE_MUTEX_WEK070601_HPP
|
||||
|
||||
// Change Log:
|
||||
// 8 Feb 01 WEKEMPF Initial version.
|
||||
// 1 Jun 01 WEKEMPF Modified to use xtime for time outs. Factored out
|
||||
// to three classes, mutex, try_mutex and timed_mutex.
|
||||
// 11 Jun 01 WEKEMPF Modified to use PTHREAD_MUTEX_RECURSIVE if available.
|
||||
// 3 Jan 03 WEKEMPF Modified for DLL implementation.
|
||||
|
||||
40
include/boost/thread/thread_time.hpp
Normal file
40
include/boost/thread/thread_time.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef BOOST_THREAD_TIME_HPP
|
||||
#define BOOST_THREAD_TIME_HPP
|
||||
#include <boost/date_time/microsec_time_clock.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
typedef boost::posix_time::ptime system_time;
|
||||
|
||||
inline system_time get_system_time()
|
||||
{
|
||||
return boost::date_time::microsec_clock<system_time>::universal_time();
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
inline system_time get_system_time_sentinel()
|
||||
{
|
||||
return system_time(boost::posix_time::pos_infin);
|
||||
}
|
||||
|
||||
inline unsigned get_milliseconds_until(system_time const& target_time)
|
||||
{
|
||||
if(target_time.is_pos_infinity())
|
||||
{
|
||||
return ~0u;
|
||||
}
|
||||
system_time const now=get_system_time();
|
||||
if(target_time<=now)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return (target_time-now).total_milliseconds();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
120
include/boost/thread/win32/basic_recursive_mutex.hpp
Normal file
120
include/boost/thread/win32/basic_recursive_mutex.hpp
Normal file
@@ -0,0 +1,120 @@
|
||||
#ifndef BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP
|
||||
#define BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP
|
||||
|
||||
// basic_recursive_mutex.hpp
|
||||
//
|
||||
// (C) Copyright 2006-7 Anthony Williams
|
||||
//
|
||||
// Distributed under 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)
|
||||
|
||||
#include "thread_primitives.hpp"
|
||||
#include "basic_timed_mutex.hpp"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename underlying_mutex_type>
|
||||
struct basic_recursive_mutex_impl
|
||||
{
|
||||
long recursion_count;
|
||||
long locking_thread_id;
|
||||
underlying_mutex_type mutex;
|
||||
|
||||
void initialize()
|
||||
{
|
||||
recursion_count=0;
|
||||
locking_thread_id=0;
|
||||
mutex.initialize();
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
mutex.destroy();
|
||||
}
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
long const current_thread_id=win32::GetCurrentThreadId();
|
||||
return try_recursive_lock(current_thread_id) || try_basic_lock(current_thread_id);
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
long const current_thread_id=win32::GetCurrentThreadId();
|
||||
if(!try_recursive_lock(current_thread_id))
|
||||
{
|
||||
mutex.lock();
|
||||
BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
|
||||
recursion_count=1;
|
||||
}
|
||||
}
|
||||
bool timed_lock(::boost::system_time const& target)
|
||||
{
|
||||
long const current_thread_id=win32::GetCurrentThreadId();
|
||||
return try_recursive_lock(current_thread_id) || try_timed_lock(current_thread_id,target);
|
||||
}
|
||||
long get_active_count()
|
||||
{
|
||||
return mutex.get_active_count();
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
if(!--recursion_count)
|
||||
{
|
||||
BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,0);
|
||||
mutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
bool locked()
|
||||
{
|
||||
return mutex.locked();
|
||||
}
|
||||
|
||||
private:
|
||||
bool try_recursive_lock(long current_thread_id)
|
||||
{
|
||||
if(::boost::detail::interlocked_read_acquire(&locking_thread_id)==current_thread_id)
|
||||
{
|
||||
++recursion_count;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool try_basic_lock(long current_thread_id)
|
||||
{
|
||||
if(mutex.try_lock())
|
||||
{
|
||||
BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
|
||||
recursion_count=1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool try_timed_lock(long current_thread_id,::boost::system_time const& target)
|
||||
{
|
||||
if(mutex.timed_lock(target))
|
||||
{
|
||||
BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
|
||||
recursion_count=1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_mutex;
|
||||
typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_timed_mutex;
|
||||
}
|
||||
}
|
||||
|
||||
#define BOOST_BASIC_RECURSIVE_MUTEX_INITIALIZER {0}
|
||||
|
||||
#endif
|
||||
157
include/boost/thread/win32/basic_timed_mutex.hpp
Normal file
157
include/boost/thread/win32/basic_timed_mutex.hpp
Normal file
@@ -0,0 +1,157 @@
|
||||
#ifndef BOOST_BASIC_TIMED_MUTEX_WIN32_HPP
|
||||
#define BOOST_BASIC_TIMED_MUTEX_WIN32_HPP
|
||||
|
||||
// basic_timed_mutex_win32.hpp
|
||||
//
|
||||
// (C) Copyright 2006 Anthony Williams
|
||||
//
|
||||
// Distributed under 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)
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include "thread_primitives.hpp"
|
||||
#include "interlocked_read.hpp"
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct basic_timed_mutex
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(long,lock_flag_value=0x80000000);
|
||||
long active_count;
|
||||
void* event;
|
||||
|
||||
void initialize()
|
||||
{
|
||||
active_count=0;
|
||||
event=0;
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
void* const old_event=BOOST_INTERLOCKED_EXCHANGE_POINTER(&event,0);
|
||||
if(old_event)
|
||||
{
|
||||
win32::CloseHandle(old_event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
long old_count=active_count&~lock_flag_value;
|
||||
do
|
||||
{
|
||||
long const current_count=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,(old_count+1)|lock_flag_value,old_count);
|
||||
if(current_count==old_count)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
old_count=current_count;
|
||||
}
|
||||
while(!(old_count&lock_flag_value));
|
||||
return false;
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
bool const success=timed_lock(::boost::detail::get_system_time_sentinel());
|
||||
BOOST_ASSERT(success);
|
||||
}
|
||||
bool timed_lock(::boost::system_time const& wait_until)
|
||||
{
|
||||
long old_count=active_count;
|
||||
while(true)
|
||||
{
|
||||
long const current_count=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,(old_count+1)|lock_flag_value,old_count);
|
||||
if(current_count==old_count)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_count=current_count;
|
||||
}
|
||||
|
||||
if(old_count&lock_flag_value)
|
||||
{
|
||||
bool lock_acquired=false;
|
||||
void* const sem=get_event();
|
||||
++old_count; // we're waiting, too
|
||||
do
|
||||
{
|
||||
old_count-=(lock_flag_value+1); // there will be one less active thread on this mutex when it gets unlocked
|
||||
if(win32::WaitForSingleObject(sem,::boost::detail::get_milliseconds_until(wait_until))!=0)
|
||||
{
|
||||
BOOST_INTERLOCKED_DECREMENT(&active_count);
|
||||
return false;
|
||||
}
|
||||
do
|
||||
{
|
||||
long const current_count=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,old_count|lock_flag_value,old_count);
|
||||
if(current_count==old_count)
|
||||
{
|
||||
break;
|
||||
}
|
||||
old_count=current_count;
|
||||
}
|
||||
while(!(old_count&lock_flag_value));
|
||||
lock_acquired=!(old_count&lock_flag_value);
|
||||
}
|
||||
while(!lock_acquired);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
long get_active_count()
|
||||
{
|
||||
return ::boost::detail::interlocked_read_acquire(&active_count);
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
long const offset=lock_flag_value+1;
|
||||
long old_count=BOOST_INTERLOCKED_EXCHANGE_ADD(&active_count,-offset);
|
||||
|
||||
if(old_count>offset)
|
||||
{
|
||||
win32::SetEvent(get_event());
|
||||
}
|
||||
}
|
||||
|
||||
bool locked()
|
||||
{
|
||||
return get_active_count()>=lock_flag_value;
|
||||
}
|
||||
|
||||
private:
|
||||
void* get_event()
|
||||
{
|
||||
void* current_event=::boost::detail::interlocked_read_acquire(&event);
|
||||
|
||||
if(!current_event)
|
||||
{
|
||||
void* const new_event=win32::create_anonymous_event(win32::auto_reset_event,win32::event_initially_reset);
|
||||
void* const old_event=BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&event,new_event,0);
|
||||
if(old_event!=0)
|
||||
{
|
||||
win32::CloseHandle(new_event);
|
||||
return old_event;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new_event;
|
||||
}
|
||||
}
|
||||
return current_event;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#define BOOST_BASIC_TIMED_MUTEX_INITIALIZER {0}
|
||||
|
||||
#endif
|
||||
@@ -9,7 +9,7 @@
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/detail/interlocked.hpp>
|
||||
#ifdef BOOST_MSVC
|
||||
|
||||
extern "C" void _ReadWriteBarrier(void);
|
||||
#pragma intrinsic(_ReadWriteBarrier)
|
||||
@@ -33,4 +33,26 @@ namespace boost
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/detail/interlocked.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
inline long interlocked_read_acquire(long volatile* x)
|
||||
{
|
||||
return BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,0,0);
|
||||
}
|
||||
inline void* interlocked_read_acquire(void* volatile* x)
|
||||
{
|
||||
return BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(x,0,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
61
include/boost/thread/win32/mutex.hpp
Normal file
61
include/boost/thread/win32/mutex.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef BOOST_THREAD_WIN32_MUTEX_HPP
|
||||
#define BOOST_THREAD_WIN32_MUTEX_HPP
|
||||
// (C) Copyright 2005-7 Anthony Williams
|
||||
// Distributed under 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)
|
||||
|
||||
#include "basic_timed_mutex.hpp"
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
#include <boost/thread/locks.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
typedef ::boost::detail::basic_timed_mutex underlying_mutex;
|
||||
}
|
||||
|
||||
class mutex:
|
||||
boost::noncopyable,
|
||||
public ::boost::detail::underlying_mutex
|
||||
{
|
||||
public:
|
||||
mutex()
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
~mutex()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
typedef unique_lock<mutex> scoped_lock;
|
||||
typedef scoped_lock scoped_try_lock;
|
||||
};
|
||||
|
||||
typedef mutex try_mutex;
|
||||
|
||||
class timed_mutex:
|
||||
boost::noncopyable,
|
||||
public ::boost::detail::basic_timed_mutex
|
||||
{
|
||||
public:
|
||||
timed_mutex()
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
~timed_mutex()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
typedef unique_lock<timed_mutex> scoped_timed_lock;
|
||||
typedef scoped_timed_lock scoped_try_lock;
|
||||
typedef scoped_timed_lock scoped_lock;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
61
include/boost/thread/win32/recursive_mutex.hpp
Normal file
61
include/boost/thread/win32/recursive_mutex.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef BOOST_RECURSIVE_MUTEX_WIN32_HPP
|
||||
#define BOOST_RECURSIVE_MUTEX_WIN32_HPP
|
||||
|
||||
// recursive_mutex.hpp
|
||||
//
|
||||
// (C) Copyright 2006-7 Anthony Williams
|
||||
//
|
||||
// Distributed under 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)
|
||||
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
#include "basic_recursive_mutex.hpp"
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
#include <boost/thread/locks.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
class recursive_mutex:
|
||||
boost::noncopyable,
|
||||
public ::boost::detail::basic_recursive_mutex
|
||||
{
|
||||
public:
|
||||
recursive_mutex()
|
||||
{
|
||||
::boost::detail::basic_recursive_mutex::initialize();
|
||||
}
|
||||
~recursive_mutex()
|
||||
{
|
||||
::boost::detail::basic_recursive_mutex::destroy();
|
||||
}
|
||||
|
||||
typedef unique_lock<recursive_mutex> scoped_lock;
|
||||
typedef scoped_lock scoped_try_lock;
|
||||
};
|
||||
|
||||
typedef recursive_mutex recursive_try_mutex;
|
||||
|
||||
class recursive_timed_mutex:
|
||||
boost::noncopyable,
|
||||
public ::boost::detail::basic_recursive_timed_mutex
|
||||
{
|
||||
public:
|
||||
recursive_timed_mutex()
|
||||
{
|
||||
::boost::detail::basic_recursive_timed_mutex::initialize();
|
||||
}
|
||||
~recursive_timed_mutex()
|
||||
{
|
||||
::boost::detail::basic_recursive_timed_mutex::destroy();
|
||||
}
|
||||
|
||||
typedef unique_lock<recursive_timed_mutex> scoped_timed_lock;
|
||||
typedef scoped_timed_lock scoped_try_lock;
|
||||
typedef scoped_timed_lock scoped_lock;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -113,13 +113,21 @@ namespace boost
|
||||
inline handle create_anonymous_event(event_type type,initial_event_state state)
|
||||
{
|
||||
handle const res=CreateEventA(0,type,state,0);
|
||||
return res?res:throw thread_resource_error();
|
||||
if(!res)
|
||||
{
|
||||
throw thread_resource_error();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
inline handle create_anonymous_semaphore(long initial_count,long max_count)
|
||||
{
|
||||
handle const res=CreateSemaphoreA(NULL,initial_count,max_count,NULL);
|
||||
return res?res:throw thread_resource_error();
|
||||
if(!res)
|
||||
{
|
||||
throw thread_resource_error();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
inline handle duplicate_handle(handle source)
|
||||
@@ -128,7 +136,11 @@ namespace boost
|
||||
long const same_access_flag=2;
|
||||
handle new_handle=0;
|
||||
bool const success=DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0;
|
||||
return success?new_handle:throw thread_resource_error();
|
||||
if(!success)
|
||||
{
|
||||
throw thread_resource_error();
|
||||
}
|
||||
return new_handle;
|
||||
}
|
||||
|
||||
inline void release_semaphore(handle semaphore,long count)
|
||||
|
||||
Reference in New Issue
Block a user