|
Boost-Commit : |
From: anthony_at_[hidden]
Date: 2007-10-08 11:41:07
Author: anthonyw
Date: 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
New Revision: 39784
URL: http://svn.boost.org/trac/boost/changeset/39784
Log:
New mutex implementations, more akin to C++0x
Added:
trunk/boost/thread/locks.hpp (contents, props changed)
trunk/boost/thread/pthread/mutex.hpp (contents, props changed)
trunk/boost/thread/pthread/recursive_mutex.hpp (contents, props changed)
trunk/boost/thread/pthread/timespec.hpp (contents, props changed)
trunk/boost/thread/thread_time.hpp (contents, props changed)
trunk/boost/thread/win32/basic_recursive_mutex.hpp (contents, props changed)
trunk/boost/thread/win32/basic_timed_mutex.hpp (contents, props changed)
trunk/boost/thread/win32/mutex.hpp (contents, props changed)
trunk/boost/thread/win32/recursive_mutex.hpp (contents, props changed)
Text files modified:
trunk/boost/date_time/microsec_time_clock.hpp | 1
trunk/boost/thread/condition.hpp | 48 ++++-----
trunk/boost/thread/mutex.hpp | 177 ++----------------------------------
trunk/boost/thread/recursive_mutex.hpp | 191 ++-------------------------------------
trunk/boost/thread/win32/thread_primitives.hpp | 18 +++
trunk/libs/thread/build/Jamfile.v2 | 4
trunk/libs/thread/src/condition.cpp | 13 ++
trunk/libs/thread/src/thread.cpp | 1
trunk/libs/thread/test/test_mutex.cpp | 18 +-
9 files changed, 85 insertions(+), 386 deletions(-)
Modified: trunk/boost/date_time/microsec_time_clock.hpp
==============================================================================
--- trunk/boost/date_time/microsec_time_clock.hpp (original)
+++ trunk/boost/date_time/microsec_time_clock.hpp 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -16,6 +16,7 @@
#include <boost/detail/workaround.hpp>
#include "boost/date_time/c_time.hpp"
+#include "boost/date_time/time_clock.hpp"
#include "boost/cstdint.hpp"
#include "boost/shared_ptr.hpp"
Modified: trunk/boost/thread/condition.hpp
==============================================================================
--- trunk/boost/thread/condition.hpp (original)
+++ trunk/boost/thread/condition.hpp 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -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 @@
// 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 @@
if (!lock)
throw lock_error();
- do_wait(lock.m_mutex);
+ do_wait(*lock.mutex());
}
template <typename L, typename Pr>
@@ -100,7 +102,7 @@
throw lock_error();
while (!pred())
- do_wait(lock.m_mutex);
+ do_wait(*lock.mutex());
}
template <typename L>
@@ -109,7 +111,7 @@
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 @@
while (!pred())
{
- if (!do_timed_wait(lock.m_mutex, xt))
+ if (!do_timed_wait(*lock.mutex(), xt))
return false;
}
@@ -135,25 +137,22 @@
{
#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 @@
{
#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;
}
Added: trunk/boost/thread/locks.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/locks.hpp 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -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
Modified: trunk/boost/thread/mutex.hpp
==============================================================================
--- trunk/boost/thread/mutex.hpp (original)
+++ trunk/boost/thread/mutex.hpp 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -1,170 +1,15 @@
-// Copyright (C) 2001-2003
-// William E. Kempf
-//
-// 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/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 {
+#ifndef BOOST_THREAD_MUTEX_HPP
+#define BOOST_THREAD_MUTEX_HPP
-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();
+// 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)
-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);
+#include <boost/thread/detail/platform.hpp>
+#include BOOST_THREAD_PLATFORM(mutex.hpp)
-#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
Added: trunk/boost/thread/pthread/mutex.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/pthread/mutex.hpp 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -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
Added: trunk/boost/thread/pthread/recursive_mutex.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/pthread/recursive_mutex.hpp 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -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
Added: trunk/boost/thread/pthread/timespec.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/pthread/timespec.hpp 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -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
Modified: trunk/boost/thread/recursive_mutex.hpp
==============================================================================
--- trunk/boost/thread/recursive_mutex.hpp (original)
+++ trunk/boost/thread/recursive_mutex.hpp 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -1,184 +1,15 @@
-// Copyright (C) 2001-2003
-// William E. Kempf
-//
-// 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/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
-};
+#ifndef BOOST_THREAD_RECURSIVE_MUTEX_HPP
+#define BOOST_THREAD_RECURSIVE_MUTEX_HPP
-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();
+// 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)
-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);
+#include <boost/thread/detail/platform.hpp>
+#include BOOST_THREAD_PLATFORM(recursive_mutex.hpp)
-#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.
Added: trunk/boost/thread/thread_time.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/thread_time.hpp 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -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
Added: trunk/boost/thread/win32/basic_recursive_mutex.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/win32/basic_recursive_mutex.hpp 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -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
Added: trunk/boost/thread/win32/basic_timed_mutex.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/win32/basic_timed_mutex.hpp 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -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
Added: trunk/boost/thread/win32/mutex.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/win32/mutex.hpp 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -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
Added: trunk/boost/thread/win32/recursive_mutex.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/win32/recursive_mutex.hpp 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -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
Modified: trunk/boost/thread/win32/thread_primitives.hpp
==============================================================================
--- trunk/boost/thread/win32/thread_primitives.hpp (original)
+++ trunk/boost/thread/win32/thread_primitives.hpp 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -113,13 +113,21 @@
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 @@
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)
Modified: trunk/libs/thread/build/Jamfile.v2
==============================================================================
--- trunk/libs/thread/build/Jamfile.v2 (original)
+++ trunk/libs/thread/build/Jamfile.v2 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -17,9 +17,9 @@
barrier
condition
exceptions
- mutex
+# mutex
# once
- recursive_mutex
+# recursive_mutex
# read_write_mutex
thread
tss_hooks
Modified: trunk/libs/thread/src/condition.cpp
==============================================================================
--- trunk/libs/thread/src/condition.cpp (original)
+++ trunk/libs/thread/src/condition.cpp 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -342,6 +342,9 @@
res = pthread_cond_init(&m_condition, 0);
if (res != 0)
throw thread_resource_error();
+ res = pthread_mutex_init(&m_mutex, 0);
+ if (res != 0)
+ throw thread_resource_error();
}
condition_impl::~condition_impl()
@@ -349,20 +352,30 @@
int res = 0;
res = pthread_cond_destroy(&m_condition);
assert(res == 0);
+ res = pthread_mutex_destroy(&m_mutex);
+ assert(res == 0);
}
void condition_impl::notify_one()
{
int res = 0;
+ res = pthread_mutex_lock(&m_mutex);
+ assert(res == 0);
res = pthread_cond_signal(&m_condition);
assert(res == 0);
+ res = pthread_mutex_unlock(&m_mutex);
+ assert(res == 0);
}
void condition_impl::notify_all()
{
int res = 0;
+ res = pthread_mutex_lock(&m_mutex);
+ assert(res == 0);
res = pthread_cond_broadcast(&m_condition);
assert(res == 0);
+ res = pthread_mutex_unlock(&m_mutex);
+ assert(res == 0);
}
void condition_impl::do_wait(pthread_mutex_t* pmutex)
Modified: trunk/libs/thread/src/thread.cpp
==============================================================================
--- trunk/libs/thread/src/thread.cpp (original)
+++ trunk/libs/thread/src/thread.cpp 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -10,6 +10,7 @@
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/thread/condition.hpp>
+#include <boost/thread/locks.hpp>
#include <cassert>
#if defined(BOOST_HAS_WINTHREADS)
Modified: trunk/libs/thread/test/test_mutex.cpp
==============================================================================
--- trunk/libs/thread/test/test_mutex.cpp (original)
+++ trunk/libs/thread/test/test_mutex.cpp 2007-10-08 11:41:05 EDT (Mon, 08 Oct 2007)
@@ -8,7 +8,7 @@
#include <boost/thread/mutex.hpp>
#include <boost/thread/recursive_mutex.hpp>
-#include <boost/thread/xtime.hpp>
+#include <boost/thread/thread_time.hpp>
#include <boost/thread/condition.hpp>
#include <boost/test/unit_test.hpp>
@@ -29,7 +29,7 @@
// Test the lock's constructors.
{
- lock_type lock(mutex, false);
+ lock_type lock(mutex, boost::defer_lock);
BOOST_CHECK(!lock);
}
lock_type lock(mutex);
@@ -69,10 +69,10 @@
BOOST_CHECK(lock ? true : false);
}
{
- try_lock_type lock(mutex, false);
+ try_lock_type lock(mutex, boost::defer_lock);
BOOST_CHECK(!lock);
}
- try_lock_type lock(mutex, true);
+ try_lock_type lock(mutex);
BOOST_CHECK(lock ? true : false);
// Construct and initialize an xtime for a fast time out.
@@ -110,16 +110,16 @@
// Test the lock's constructors.
{
// Construct and initialize an xtime for a fast time out.
- boost::xtime xt = delay(0, 100);
+ boost::system_time xt = boost::get_system_time()+boost::posix_time::milliseconds(100);
timed_lock_type lock(mutex, xt);
BOOST_CHECK(lock ? true : false);
}
{
- timed_lock_type lock(mutex, false);
+ timed_lock_type lock(mutex, boost::defer_lock);
BOOST_CHECK(!lock);
}
- timed_lock_type lock(mutex, true);
+ timed_lock_type lock(mutex);
BOOST_CHECK(lock ? true : false);
// Construct and initialize an xtime for a fast time out.
@@ -139,8 +139,8 @@
BOOST_CHECK(lock ? true : false);
lock.unlock();
BOOST_CHECK(!lock);
- xt = delay(0, 100);
- BOOST_CHECK(lock.timed_lock(xt));
+ boost::system_time target = boost::get_system_time()+boost::posix_time::milliseconds(100);
+ BOOST_CHECK(lock.timed_lock(target));
BOOST_CHECK(lock ? true : false);
}
};
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk