Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r85831 - in trunk: boost/sync boost/sync/condition_variables boost/sync/detail boost/sync/detail/condition_variables boost/sync/detail/mutexes boost/sync/mutexes boost/sync/support boost/sync/traits libs/sync/doc
From: andrey.semashev_at_[hidden]
Date: 2013-09-22 12:54:09


Author: andysem
Date: 2013-09-22 12:54:09 EDT (Sun, 22 Sep 2013)
New Revision: 85831
URL: http://svn.boost.org/trac/boost/changeset/85831

Log:
Implementing condition_variable. Work in progress.

Added:
   trunk/boost/sync/condition_variables/
   trunk/boost/sync/condition_variables.hpp (contents, props changed)
   trunk/boost/sync/condition_variables/condition_variable.hpp (contents, props changed)
   trunk/boost/sync/condition_variables/cv_status.hpp (contents, props changed)
   trunk/boost/sync/detail/condition_variables/
   trunk/boost/sync/detail/condition_variables/condition_variable_posix.hpp (contents, props changed)
   trunk/boost/sync/traits/
   trunk/boost/sync/traits/is_condition_variable_compatible.hpp (contents, props changed)
Text files modified:
   trunk/boost/sync/condition_variables.hpp | 25 +++
   trunk/boost/sync/condition_variables/condition_variable.hpp | 288 ++++++++++++++++++++++++++++++++++++++++
   trunk/boost/sync/condition_variables/cv_status.hpp | 43 +++++
   trunk/boost/sync/detail/condition_variables/condition_variable_posix.hpp | 222 ++++++++++++++++++++++++++++++
   trunk/boost/sync/detail/mutexes/mutex_posix.hpp | 2
   trunk/boost/sync/detail/mutexes/mutex_windows.hpp | 3
   trunk/boost/sync/detail/mutexes/timed_mutex_posix.hpp | 45 -----
   trunk/boost/sync/detail/mutexes/timed_mutex_windows.hpp | 3
   trunk/boost/sync/detail/pthread.hpp | 41 +++++
   trunk/boost/sync/mutexes/timed_mutex.hpp | 6
   trunk/boost/sync/support/boost_chrono.hpp | 3
   trunk/boost/sync/support/boost_date_time.hpp | 2
   trunk/boost/sync/support/posix_time.hpp | 1
   trunk/boost/sync/support/std_chrono.hpp | 7
   trunk/boost/sync/traits/is_condition_variable_compatible.hpp | 40 +++++
   trunk/libs/sync/doc/Jamfile.v2 | 2
   16 files changed, 690 insertions(+), 43 deletions(-)

Added: trunk/boost/sync/condition_variables.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/sync/condition_variables.hpp 2013-09-22 12:54:09 EDT (Sun, 22 Sep 2013) (r85831)
@@ -0,0 +1,25 @@
+/*
+ * 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 2013 Andrey Semashev
+ */
+/*!
+ * \file condition_variables.hpp
+ *
+ * \brief This header includes all condition variable types.
+ */
+
+#ifndef BOOST_SYNC_CONDITION_VARIABLES_HPP_INCLUDED_
+#define BOOST_SYNC_CONDITION_VARIABLES_HPP_INCLUDED_
+
+#include <boost/sync/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#include <boost/sync/condition_variables/condition_variable.hpp>
+
+#endif // BOOST_SYNC_CONDITION_VARIABLES_HPP_INCLUDED_

Added: trunk/boost/sync/condition_variables/condition_variable.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/sync/condition_variables/condition_variable.hpp 2013-09-22 12:54:09 EDT (Sun, 22 Sep 2013) (r85831)
@@ -0,0 +1,288 @@
+/*
+ * 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 2013 Andrey Semashev
+ */
+/*!
+ * \file sync/condition_variables/condition_variable.hpp
+ *
+ * \brief This header defines a basic condition variable primitive.
+ */
+
+#ifndef BOOST_SYNC_CONDITION_VARIABLES_CONDITION_VARIABLE_HPP_INCLUDED_
+#define BOOST_SYNC_CONDITION_VARIABLES_CONDITION_VARIABLE_HPP_INCLUDED_
+
+#if defined(BOOST_SYNC_DETAIL_DOXYGEN)
+
+namespace boost {
+
+namespace sync {
+
+/*!
+ * \brief The condition variable class
+ */
+class condition_variable
+{
+public:
+ /*!
+ * \brief A platform-specific type of the low level mutex implementation.
+ * \note This type is only available if \c BOOST_SYNC_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE macro is defined by the library.
+ */
+ typedef unspecified native_handle_type;
+
+public:
+ /*!
+ * \brief Default constructor
+ *
+ * \b Throws: An exception in case if the operating system is unable to create the primitive (e.g. due to insufficient resources).
+ */
+ condition_variable();
+
+ /*!
+ * \brief Destructor
+ *
+ * Destroys the condition variable.
+ *
+ * \pre There are no threads blocked on the object.
+ */
+ ~condition_variable();
+
+ condition_variable(condition_variable const&) = delete;
+ condition_variable& operator= (condition_variable const&) = delete;
+
+ /*!
+ * \brief Wakes up one thread blocked on the object
+ */
+ void notify_one() noexcept;
+
+ /*!
+ * \brief Wakes up all threads blocked on the object
+ */
+ void notify_all() noexcept;
+
+ /*!
+ * \brief Blocks the current thread on the object
+ *
+ * Atomically unlocks the mutex and blocks on the object. When unblocked, it locks the mutex and returns.
+ * The function can unblock upon another thread calling \c notify_one(), \c notify_all() or spuriously.
+ *
+ * \param lock Lock object
+ *
+ * \pre \c Mutex is on of the mutex types compatible with \c condition_variable.
+ * \pre <tt>lock.owns_lock() == true</tt> and <tt>lock.mutex()</tt> is locked by the current thread.
+ * \pre There are no other threads blocked on the object or the blocked threads used the same mutex returned by <tt>lock.mutex()</tt> to block on this object.
+ *
+ * \b Throws: An exception in case if the operating system is unable to fulfill the request. The mutex is left in the locked state in case of exception.
+ */
+ template< typename Mutex >
+ void wait(unique_lock< Mutex >& lock);
+
+ /*!
+ * \brief Blocks the current thread on the object until the predicate is satisfied
+ *
+ * Works equivalent to:
+ *
+ * <code>
+ * while (!pred())
+ * wait(lock);
+ * </code>
+ *
+ * \param lock Lock object
+ * \param pred Condition predicate
+ *
+ * \pre \c Mutex is on of the mutex types compatible with \c condition_variable.
+ * \pre <tt>lock.owns_lock() == true</tt> and <tt>lock.mutex()</tt> is locked by the current thread.
+ * \pre There are no other threads blocked on the object or the blocked threads used the same mutex returned by <tt>lock.mutex()</tt> to block on this object.
+ *
+ * \b Throws: An exception in case if the operating system is unable to fulfill the request. The mutex is left in the locked state in case of exception.
+ */
+ template< typename Mutex, typename Predicate >
+ void wait(unique_lock< Mutex >& lock, Predicate pred);
+
+ /*!
+ * \brief Blocks the current thread on the object until the timeout expires
+ *
+ * Atomically unlocks the mutex and blocks on the object. When unblocked, it locks the mutex and returns.
+ * The function can unblock after the specified timeout expires, upon another thread calling \c notify_one(), \c notify_all() or spuriously, whichever happens first.
+ * The timeout can be specified as an absolute time point or duration.
+ *
+ * \param lock Lock object
+ * \param timeout Relative or absolute timeout. If timeout is relative, the time is measured according to the system clock.
+ *
+ * \pre \c Mutex is on of the mutex types compatible with \c condition_variable.
+ * \pre <tt>lock.owns_lock() == true</tt> and <tt>lock.mutex()</tt> is locked by the current thread.
+ * \pre There are no other threads blocked on the object or the blocked threads used the same mutex returned by <tt>lock.mutex()</tt> to block on this object.
+ *
+ * \return \c true if the function returned before the timeout expired, otherwise \c false.
+ *
+ * \b Throws: An exception in case if the operating system is unable to fulfill the request. The mutex is left in the locked state in case of exception.
+ *
+ * \note In order to use this method, a supplementary header must be included from boost/sync/support to enable support for particular time units.
+ */
+ template< typename Mutex, typename Time >
+ bool timed_wait(unique_lock< Mutex >& lock, Time const& timeout);
+
+ /*!
+ * \brief Blocks the current thread on the object until the predicate is satisfied or the timeout expires
+ *
+ * If the timeout is an absolute time point, works equivalent to:
+ *
+ * <code>
+ * while (!pred())
+ * if (!timed_wait(lock, timeout))
+ * return pred();
+ * </code>
+ *
+ * otherwise works as if equivalent to:
+ *
+ * <code>
+ * auto abs_timeout = chrono::system_clock::now() + timeout;
+ * while (!pred())
+ * if (!timed_wait(lock, abs_timeout))
+ * return pred();
+ * </code>
+ *
+ * \param lock Lock object
+ * \param timeout Relative or absolute timeout. If timeout is relative, the time is measured according to the system clock.
+ * \param pred Condition predicate
+ *
+ * \pre \c Mutex is on of the mutex types compatible with \c condition_variable.
+ * \pre <tt>lock.owns_lock() == true</tt> and <tt>lock.mutex()</tt> is locked by the current thread.
+ * \pre There are no other threads blocked on the object or the blocked threads used the same mutex returned by <tt>lock.mutex()</tt> to block on this object.
+ *
+ * \b Throws: An exception in case if the operating system is unable to fulfill the request. The mutex is left in the locked state in case of exception.
+ *
+ * \note In order to use this method, a supplementary header must be included from boost/sync/support to enable support for particular time units.
+ */
+ template< typename Mutex, typename Time, typename Predicate >
+ bool timed_wait(unique_lock< Mutex >& lock, Time const& timeout, Predicate pred);
+
+ /*!
+ * \brief Blocks the current thread on the object until the timeout expires
+ *
+ * Atomically unlocks the mutex and blocks on the object. When unblocked, it locks the mutex and returns.
+ * The function can unblock after the specified timeout expires, upon another thread calling \c notify_one(), \c notify_all() or spuriously, whichever happens first.
+ * The timeout must be specified as a time duration.
+ *
+ * \param lock Lock object
+ * \param timeout Relative timeout. The time is measured according to the system clock.
+ *
+ * \pre \c Mutex is on of the mutex types compatible with \c condition_variable.
+ * \pre <tt>lock.owns_lock() == true</tt> and <tt>lock.mutex()</tt> is locked by the current thread.
+ * \pre There are no other threads blocked on the object or the blocked threads used the same mutex returned by <tt>lock.mutex()</tt> to block on this object.
+ *
+ * \return \c cv_status::no_timeout if the function returned before the timeout expired, otherwise \c cv_status::timeout.
+ *
+ * \b Throws: An exception in case if the operating system is unable to fulfill the request. The mutex is left in the locked state in case of exception.
+ *
+ * \note In order to use this method, a supplementary header must be included from boost/sync/support to enable support for particular time units.
+ */
+ template< typename Mutex, typename Duration >
+ cv_status wait_for(unique_lock< Mutex >& lock, Duration const& rel_timeout);
+
+ /*!
+ * \brief Blocks the current thread on the object until the timeout expires
+ *
+ * Works equivalent to:
+ *
+ * <code>
+ * return wait_until(lock, chrono::system_clock::now() + rel_timeout, pred);
+ * </code>
+ *
+ * \param lock Lock object
+ * \param timeout Relative timeout. The time is measured according to the system clock.
+ * \param pred Condition predicate
+ *
+ * \pre \c Mutex is on of the mutex types compatible with \c condition_variable.
+ * \pre <tt>lock.owns_lock() == true</tt> and <tt>lock.mutex()</tt> is locked by the current thread.
+ * \pre There are no other threads blocked on the object or the blocked threads used the same mutex returned by <tt>lock.mutex()</tt> to block on this object.
+ *
+ * \b Throws: An exception in case if the operating system is unable to fulfill the request. The mutex is left in the locked state in case of exception.
+ *
+ * \note In order to use this method, a supplementary header must be included from boost/sync/support to enable support for particular time units.
+ */
+ template< typename Mutex, typename Duration, typename Predicate >
+ bool wait_for(unique_lock< Mutex >& lock, Duration const& rel_timeout, Predicate pred);
+
+ /*!
+ * \brief Blocks the current thread on the object until the timeout expires
+ *
+ * Atomically unlocks the mutex and blocks on the object. When unblocked, it locks the mutex and returns.
+ * The function can unblock after the specified timeout expires, upon another thread calling \c notify_one(), \c notify_all() or spuriously, whichever happens first.
+ * The timeout must be specified as an absolute time point.
+ *
+ * \param lock Lock object
+ * \param timeout Absolute timeout
+ *
+ * \pre \c Mutex is on of the mutex types compatible with \c condition_variable.
+ * \pre <tt>lock.owns_lock() == true</tt> and <tt>lock.mutex()</tt> is locked by the current thread.
+ * \pre There are no other threads blocked on the object or the blocked threads used the same mutex returned by <tt>lock.mutex()</tt> to block on this object.
+ *
+ * \return \c cv_status::no_timeout if the function returned before the timeout expired, otherwise \c cv_status::timeout.
+ *
+ * \b Throws: An exception in case if the operating system is unable to fulfill the request. The mutex is left in the locked state in case of exception.
+ *
+ * \note In order to use this method, a supplementary header must be included from boost/sync/support to enable support for particular time units.
+ */
+ template< typename Mutex, typename TimePoint >
+ cv_status wait_until(unique_lock< Mutex >& lock, TimePoint const& abs_timeout);
+
+ /*!
+ * \brief Blocks the current thread on the object until the timeout expires
+ *
+ * Works equivalent to:
+ *
+ * <code>
+ * while (!pred())
+ * if (wait_until(lock, timeout) == cv_status::timeout)
+ * return pred();
+ * </code>
+ *
+ * \param lock Lock object
+ * \param timeout Absolute timeout
+ * \param pred Condition predicate
+ *
+ * \pre \c Mutex is on of the mutex types compatible with \c condition_variable.
+ * \pre <tt>lock.owns_lock() == true</tt> and <tt>lock.mutex()</tt> is locked by the current thread.
+ * \pre There are no other threads blocked on the object or the blocked threads used the same mutex returned by <tt>lock.mutex()</tt> to block on this object.
+ *
+ * \b Throws: An exception in case if the operating system is unable to fulfill the request. The mutex is left in the locked state in case of exception.
+ *
+ * \note In order to use this method, a supplementary header must be included from boost/sync/support to enable support for particular time units.
+ */
+ template< typename Mutex, typename TimePoint, typename Predicate >
+ bool wait_until(unique_lock< Mutex >& lock, TimePoint const& abs_timeout, Predicate pred);
+
+ /*!
+ * \brief Returns a handle that represents a native operating system primitive that implements the condition variable
+ *
+ * \note This method is only available if \c BOOST_SYNC_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE macro is defined by the library.
+ */
+ native_handle_type native_handle() noexcept;
+};
+
+} // namespace sync
+
+} // namespace boost
+
+#else // defined(BOOST_SYNC_DETAIL_DOXYGEN)
+
+#include <boost/sync/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(BOOST_SYNC_DETAIL_PLATFORM_PTHREAD)
+#include <boost/sync/detail/condition_variables/condition_variable_posix.hpp>
+#elif defined(BOOST_SYNC_DETAIL_PLATFORM_WINAPI)
+//#include <boost/sync/detail/condition_variables/condition_variable_windows.hpp>
+#else
+#error Boost.Sync: Unsupported threading API
+#endif
+
+#endif // defined(BOOST_SYNC_DETAIL_DOXYGEN)
+
+#endif // BOOST_SYNC_CONDITION_VARIABLES_CONDITION_VARIABLE_HPP_INCLUDED_

Added: trunk/boost/sync/condition_variables/cv_status.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/sync/condition_variables/cv_status.hpp 2013-09-22 12:54:09 EDT (Sun, 22 Sep 2013) (r85831)
@@ -0,0 +1,43 @@
+/*
+ * 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 2011 Vicente J. Botet Escriba
+ */
+/*!
+ * \file sync/condition_variables/cv_status.hpp
+ *
+ * \brief This header defines \c cv_status enumeration.
+ */
+
+#ifndef BOOST_SYNC_CONDITION_VARIABLES_CV_STATUS_HPP_INCLUDED_
+#define BOOST_SYNC_CONDITION_VARIABLES_CV_STATUS_HPP_INCLUDED_
+
+#include <boost/detail/scoped_enum_emulation.hpp>
+#include <boost/sync/detail/config.hpp>
+#include <boost/sync/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+namespace sync {
+
+//! Condition variable wait status
+BOOST_SCOPED_ENUM_DECLARE_BEGIN(cv_status)
+{
+ no_timeout, //!< The operation completed successfully before timeout
+ timeout //!< Timeout expired
+}
+BOOST_SCOPED_ENUM_DECLARE_END(cv_status)
+
+} // namespace sync
+
+} // namespace boost
+
+#include <boost/sync/detail/footer.hpp>
+
+#endif // BOOST_SYNC_CONDITION_VARIABLES_CV_STATUS_HPP_INCLUDED_

Added: trunk/boost/sync/detail/condition_variables/condition_variable_posix.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/sync/detail/condition_variables/condition_variable_posix.hpp 2013-09-22 12:54:09 EDT (Sun, 22 Sep 2013) (r85831)
@@ -0,0 +1,222 @@
+/*
+ * 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-2008 Anthony Williams
+ * (C) Copyright 2011-2012 Vicente J. Botet Escriba
+ * (C) Copyright 2013 Andrey Semashev
+ */
+/*!
+ * \file detail/condition_variables/condition_variable_posix.hpp
+ *
+ * \brief This header is the Boost.Sync library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/sync/doc/html/index.html.
+ */
+
+#ifndef BOOST_SYNC_DETAIL_CONDITION_VARIABLES_CONDITION_VARIABLE_POSIX_HPP_INCLUDED_
+#define BOOST_SYNC_DETAIL_CONDITION_VARIABLES_CONDITION_VARIABLE_POSIX_HPP_INCLUDED_
+
+#include <time.h>
+#include <cstddef>
+#include <boost/assert.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/sync/detail/config.hpp>
+#include <boost/sync/locks/unique_lock_fwd.hpp>
+#include <boost/sync/exceptions/resource_error.hpp>
+#include <boost/sync/traits/is_condition_variable_compatible.hpp>
+#include <boost/sync/detail/pthread.hpp>
+#include <boost/sync/detail/time_traits.hpp>
+#include <boost/sync/detail/time_units.hpp>
+#include <boost/sync/condition_variables/cv_status.hpp>
+#include <boost/sync/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#define BOOST_SYNC_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE
+
+namespace boost {
+
+namespace sync {
+
+BOOST_SYNC_DETAIL_OPEN_ABI_NAMESPACE {
+
+class condition_variable
+{
+public:
+ typedef pthread_cond_t* native_handle_type;
+
+private:
+ pthread_cond_t m_cond;
+
+public:
+#if defined(PTHREAD_COND_INITIALIZER)
+#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
+ BOOST_CONSTEXPR condition_variable() BOOST_NOEXCEPT : m_cond(PTHREAD_COND_INITIALIZER)
+ {
+ }
+#else
+ condition_variable() BOOST_NOEXCEPT
+ {
+ BOOST_CONSTEXPR_OR_CONST pthread_cond_t temp = PTHREAD_COND_INITIALIZER;
+ m_cond = temp;
+ }
+#endif
+#else // defined(PTHREAD_COND_INITIALIZER)
+ condition_variable()
+ {
+ int const res = pthread_cond_init(&m_cond, NULL);
+ if (res)
+ BOOST_THROW_EXCEPTION(resource_error(res, "boost:: timed_mutex constructor failed in pthread_cond_init"));
+ }
+#endif // defined(PTHREAD_COND_INITIALIZER)
+
+ ~condition_variable()
+ {
+ BOOST_VERIFY(::pthread_cond_destroy(&m_cond) == 0);
+ }
+
+ void notify_one() BOOST_NOEXCEPT
+ {
+ BOOST_VERIFY(::pthread_cond_signal(&m_cond) == 0);
+ }
+
+ void notify_all() BOOST_NOEXCEPT
+ {
+ BOOST_VERIFY(::pthread_cond_broadcast(&m_cond) == 0);
+ }
+
+ template< typename Mutex >
+ typename enable_if< is_condition_variable_compatible< Mutex >, void >::type wait(unique_lock< Mutex >& lock)
+ {
+ BOOST_ASSERT(lock.owns_lock());
+ int const res = sync::detail::posix::pthread_cond_wait(&m_cond, lock.mutex()->native_handle());
+ if (res != 0)
+ BOOST_THROW_EXCEPTION(runtime_exception(res, "boost::sync::condition_variable::wait failed in pthread_cond_wait"));
+ }
+
+ template< typename Mutex, typename Predicate >
+ typename enable_if< is_condition_variable_compatible< Mutex >, void >::type wait(unique_lock< Mutex >& lock, Predicate pred)
+ {
+ while (!pred())
+ this->wait(lock);
+ }
+
+ template< typename Mutex, typename Time >
+ typename enable_if_c< sync::detail::time_traits< Time >::is_specialized, bool >::type timed_wait(unique_lock< Mutex >& lock, Time const& t)
+ {
+ return priv_timed_wait(lock, sync::detail::time_traits< Time >::to_sync_unit(t));
+ }
+
+ template< typename Mutex, typename TimePoint, typename Predicate >
+ typename detail::enable_if_tag< TimePoint, detail::time_point_tag, bool >::type timed_wait(unique_lock< Mutex >& lock, TimePoint const& t, Predicate pred)
+ {
+ typedef typename sync::detail::time_traits< TimePoint >::unit_type unit_type;
+ unit_type abs_timeout = sync::detail::time_traits< TimePoint >::to_sync_unit(t);
+ while (!pred())
+ {
+ if (!this->priv_timed_wait(lock, abs_timeout))
+ return pred();
+ }
+ return true;
+ }
+
+ template< typename Mutex, typename Duration, typename Predicate >
+ typename detail::enable_if_tag< Duration, detail::time_duration_tag, bool >::type timed_wait(unique_lock< Mutex >& lock, Duration const& t, Predicate pred)
+ {
+ sync::detail::system_time_point abs_timeout = sync::detail::system_time_point::now() + sync::detail::time_traits< Duration >::to_sync_unit(t);
+ while (!pred())
+ {
+ if (!this->priv_timed_wait(lock, abs_timeout))
+ return pred();
+ }
+ return true;
+ }
+
+ template< typename Duration >
+ typename detail::enable_if_tag< Duration, detail::time_duration_tag, bool >::type try_lock_for(Duration const& rel_time)
+ {
+ return priv_timed_lock(sync::detail::time_traits< Duration >::to_sync_unit(rel_time));
+ }
+
+ template< typename TimePoint >
+ typename detail::enable_if_tag< TimePoint, detail::time_point_tag, bool >::type try_lock_until(TimePoint const& abs_time)
+ {
+ return priv_timed_lock(sync::detail::time_traits< TimePoint >::to_sync_unit(abs_time));
+ }
+
+ native_handle_type native_handle() BOOST_NOEXCEPT
+ {
+ return &m_cond;
+ }
+
+ BOOST_DELETED_FUNCTION(condition_variable(condition_variable const&))
+ BOOST_DELETED_FUNCTION(condition_variable& operator= (condition_variable const&))
+
+private:
+ bool priv_timed_lock(sync::detail::system_duration dur)
+ {
+ return priv_timed_lock(sync::detail::system_time_point::now() + dur);
+ }
+
+ bool priv_timed_lock(sync::detail::system_time_point const& t)
+ {
+#if defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK)
+
+ int const res = sync::detail::posix::pthread_mutex_timedlock(&m_mutex, &t.get());
+
+ if (res == 0)
+ return true;
+ else if (res != ETIMEDOUT)
+ BOOST_THROW_EXCEPTION(lock_error(res, "boost: timed_mutex timedlock failed in pthread_mutex_timedlock"));
+ return false;
+
+#else // defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK)
+
+ sync::detail::posix::pthread_mutex_lock_guard const local_lock(m_mutex);
+ while (m_is_locked)
+ {
+ int const cond_res = pthread_cond_timedwait(&m_cond, &m_mutex, &t.get());
+ if (cond_res == ETIMEDOUT)
+ return false;
+ else if (cond_res != 0)
+ BOOST_THROW_EXCEPTION(lock_error(cond_res, "boost: timed_mutex timedlock failed in pthread_cond_timedwait"));
+ }
+ m_is_locked = true;
+ return true;
+
+#endif // defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK)
+ }
+
+ template< typename TimePoint >
+ bool priv_timed_lock(sync::detail::chrono_time_point< TimePoint > const& t)
+ {
+ if (try_lock())
+ return true;
+
+ typedef TimePoint time_point;
+ typedef typename time_point::clock clock;
+ typedef typename time_point::duration duration;
+ time_point now = clock::now();
+ while (now < t.get())
+ {
+ if (priv_timed_lock(sync::detail::time_traits< duration >::to_sync_unit(t.get() - now)))
+ return true;
+ now = clock::now();
+ }
+ return false;
+ }
+};
+
+} // namespace posix
+
+} // namespace sync
+
+} // namespace boost
+
+#include <boost/sync/detail/footer.hpp>
+
+#endif // BOOST_SYNC_DETAIL_CONDITION_VARIABLES_CONDITION_VARIABLE_POSIX_HPP_INCLUDED_

Modified: trunk/boost/sync/detail/mutexes/mutex_posix.hpp
==============================================================================
--- trunk/boost/sync/detail/mutexes/mutex_posix.hpp Sun Sep 22 12:06:45 2013 (r85830)
+++ trunk/boost/sync/detail/mutexes/mutex_posix.hpp 2013-09-22 12:54:09 EDT (Sun, 22 Sep 2013) (r85831)
@@ -42,6 +42,8 @@
 class mutex
 {
 public:
+ typedef void _is_condition_variable_compatible;
+
     typedef pthread_mutex_t* native_handle_type;
 
 private:

Modified: trunk/boost/sync/detail/mutexes/mutex_windows.hpp
==============================================================================
--- trunk/boost/sync/detail/mutexes/mutex_windows.hpp Sun Sep 22 12:06:45 2013 (r85830)
+++ trunk/boost/sync/detail/mutexes/mutex_windows.hpp 2013-09-22 12:54:09 EDT (Sun, 22 Sep 2013) (r85831)
@@ -45,6 +45,9 @@
 {
     friend class timed_mutex;
 
+public:
+ typedef void _is_condition_variable_compatible;
+
 private:
     enum
     {

Modified: trunk/boost/sync/detail/mutexes/timed_mutex_posix.hpp
==============================================================================
--- trunk/boost/sync/detail/mutexes/timed_mutex_posix.hpp Sun Sep 22 12:06:45 2013 (r85830)
+++ trunk/boost/sync/detail/mutexes/timed_mutex_posix.hpp 2013-09-22 12:54:09 EDT (Sun, 22 Sep 2013) (r85831)
@@ -28,7 +28,9 @@
 #include <boost/sync/detail/pthread.hpp>
 #include <boost/sync/detail/time_traits.hpp>
 #include <boost/sync/detail/time_units.hpp>
+#if !defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK)
 #include <boost/sync/detail/pthread_mutex_locks.hpp>
+#endif
 #include <boost/sync/detail/header.hpp>
 
 #ifdef BOOST_HAS_PRAGMA_ONCE
@@ -41,38 +43,13 @@
 
 namespace sync {
 
-#if defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK)
-
-namespace detail {
-
-namespace BOOST_SYNC_DETAIL_ABI_NAMESPACE {
-
-#if !defined(BOOST_SYNC_HAS_PTHREAD_EINTR_BUG)
-using ::pthread_mutex_timedlock;
-#else
-BOOST_FORCEINLINE int pthread_mutex_timedlock(pthread_mutex_t* m, const struct timespec* t)
-{
- int ret;
- do
- {
- ret = ::pthread_mutex_timedlock(m, t);
- }
- while (ret == EINTR);
- return ret;
-}
-#endif
-
-} // namespace posix
-
-} // namespace detail
-
-#endif // defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK)
-
 BOOST_SYNC_DETAIL_OPEN_ABI_NAMESPACE {
 
 class timed_mutex
 {
 public:
+ typedef void _is_condition_variable_compatible;
+
     typedef pthread_mutex_t* native_handle_type;
 
 private:
@@ -111,16 +88,12 @@
     {
         int const res = pthread_mutex_init(&m_mutex, NULL);
         if (res)
- {
             BOOST_THROW_EXCEPTION(resource_error(res, "boost:: timed_mutex constructor failed in pthread_mutex_init"));
- }
 
 #if !defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK)
         int const res2 = pthread_cond_init(&m_cond, NULL);
         if (res2)
- {
- BOOST_THROW_EXCEPTION(resource_error(res, "boost:: timed_mutex constructor failed in pthread_cond_init"));
- }
+ BOOST_THROW_EXCEPTION(resource_error(res2, "boost:: timed_mutex constructor failed in pthread_cond_init"));
         m_is_locked = false;
 #endif
     }
@@ -140,9 +113,7 @@
     {
         int const res = sync::detail::posix::pthread_mutex_lock(&m_mutex);
         if (res)
- {
             BOOST_THROW_EXCEPTION(lock_error(res, "boost: timed_mutex lock failed in pthread_mutex_lock"));
- }
     }
 
     void unlock() BOOST_NOEXCEPT
@@ -168,7 +139,7 @@
         sync::detail::posix::pthread_mutex_lock_guard const local_lock(m_mutex);
         while (m_is_locked)
         {
- BOOST_VERIFY(!pthread_cond_wait(&m_cond, &m_mutex));
+ BOOST_VERIFY(sync::detail::posix::pthread_cond_wait(&m_cond, &m_mutex) == 0);
         }
         m_is_locked = true;
     }
@@ -184,9 +155,7 @@
     {
         sync::detail::posix::pthread_mutex_lock_guard const local_lock(m_mutex);
         if (m_is_locked)
- {
             return false;
- }
         m_is_locked = true;
         return true;
     }
@@ -242,7 +211,7 @@
         sync::detail::posix::pthread_mutex_lock_guard const local_lock(m_mutex);
         while (m_is_locked)
         {
- int const cond_res = pthread_cond_timedwait(&m_cond, &m_mutex, &t.get());
+ int const cond_res = sync::detail::posix::pthread_cond_timedwait(&m_cond, &m_mutex, &t.get());
             if (cond_res == ETIMEDOUT)
                 return false;
             else if (cond_res != 0)

Modified: trunk/boost/sync/detail/mutexes/timed_mutex_windows.hpp
==============================================================================
--- trunk/boost/sync/detail/mutexes/timed_mutex_windows.hpp Sun Sep 22 12:06:45 2013 (r85830)
+++ trunk/boost/sync/detail/mutexes/timed_mutex_windows.hpp 2013-09-22 12:54:09 EDT (Sun, 22 Sep 2013) (r85831)
@@ -45,6 +45,9 @@
 
 class timed_mutex
 {
+public:
+ typedef void _is_condition_variable_compatible;
+
 private:
     mutex m_mutex;
 

Modified: trunk/boost/sync/detail/pthread.hpp
==============================================================================
--- trunk/boost/sync/detail/pthread.hpp Sun Sep 22 12:06:45 2013 (r85830)
+++ trunk/boost/sync/detail/pthread.hpp 2013-09-22 12:54:09 EDT (Sun, 22 Sep 2013) (r85831)
@@ -18,6 +18,7 @@
 #ifndef BOOST_SYNC_DETAIL_PTHREAD_HPP_INCLUDED_
 #define BOOST_SYNC_DETAIL_PTHREAD_HPP_INCLUDED_
 
+#include <time.h>
 #include <errno.h>
 #include <pthread.h>
 #include <boost/sync/detail/config.hpp>
@@ -48,7 +49,12 @@
 using ::pthread_mutex_destroy;
 using ::pthread_mutex_lock;
 using ::pthread_mutex_trylock;
+#if defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK)
+using ::pthread_mutex_timedlock;
+#endif
 using ::pthread_mutex_unlock;
+using ::pthread_cond_wait;
+using ::pthread_cond_timedwait;
 
 #else // !defined(BOOST_SYNC_HAS_PTHREAD_EINTR_BUG)
 
@@ -87,6 +93,19 @@
     return ret;
 }
 
+#if defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK)
+BOOST_FORCEINLINE int pthread_mutex_timedlock(pthread_mutex_t* m, const struct ::timespec* t)
+{
+ int ret;
+ do
+ {
+ ret = ::pthread_mutex_timedlock(m, t);
+ }
+ while (ret == EINTR);
+ return ret;
+}
+#endif
+
 BOOST_FORCEINLINE int pthread_mutex_unlock(pthread_mutex_t* m)
 {
     int ret;
@@ -98,6 +117,28 @@
     return ret;
 }
 
+BOOST_FORCEINLINE int pthread_cond_wait(pthread_cond_t* c, pthread_mutex_t* m)
+{
+ int ret;
+ do
+ {
+ ret = ::pthread_cond_wait(c, m);
+ }
+ while (ret == EINTR);
+ return ret;
+}
+
+BOOST_FORCEINLINE int pthread_cond_timedwait(pthread_cond_t* c, pthread_mutex_t* m, const struct ::timespec* t)
+{
+ int ret;
+ do
+ {
+ ret = ::pthread_cond_timedwait(c, m, t);
+ }
+ while (ret == EINTR);
+ return ret;
+}
+
 #endif // !defined(BOOST_SYNC_HAS_PTHREAD_EINTR_BUG)
 
 } // namespace posix

Modified: trunk/boost/sync/mutexes/timed_mutex.hpp
==============================================================================
--- trunk/boost/sync/mutexes/timed_mutex.hpp Sun Sep 22 12:06:45 2013 (r85830)
+++ trunk/boost/sync/mutexes/timed_mutex.hpp 2013-09-22 12:54:09 EDT (Sun, 22 Sep 2013) (r85831)
@@ -83,7 +83,7 @@
      * \note In order to use this method, a supplementary header must be included from boost/sync/support to enable support for particular time units.
      */
     template< typename Time >
- bool timed_lock(Time time);
+ bool timed_lock(Time const& time);
 
     /*!
      * \brief Attempts to lock the mutex within the specified timeout
@@ -99,7 +99,7 @@
      * \note In order to use this method, a supplementary header must be included from boost/sync/support to enable support for particular time units.
      */
     template< typename Duration >
- bool try_lock_for(Duration rel_timeout);
+ bool try_lock_for(Duration const& rel_timeout);
 
     /*!
      * \brief Attempts to lock the mutex within the specified timeout
@@ -115,7 +115,7 @@
      * \note In order to use this method, a supplementary header must be included from boost/sync/support to enable support for particular time units.
      */
     template< typename TimePoint >
- bool try_lock_until(TimePoint abs_timeout);
+ bool try_lock_until(TimePoint const& abs_timeout);
 
     /*!
      * \brief Unlocks the mutex

Modified: trunk/boost/sync/support/boost_chrono.hpp
==============================================================================
--- trunk/boost/sync/support/boost_chrono.hpp Sun Sep 22 12:06:45 2013 (r85830)
+++ trunk/boost/sync/support/boost_chrono.hpp 2013-09-22 12:54:09 EDT (Sun, 22 Sep 2013) (r85831)
@@ -36,6 +36,7 @@
 struct time_traits< boost::chrono::duration< Rep, Period > >
 {
     typedef time_duration_tag tag;
+ typedef system_duration unit_type;
 
     static BOOST_CONSTEXPR_OR_CONST bool is_specialized = true;
 
@@ -50,6 +51,7 @@
 struct time_traits< boost::chrono::time_point< Clock, Duration > >
 {
     typedef time_point_tag tag;
+ typedef chrono_time_point< boost::chrono::time_point< Clock, Duration > > unit_type;
 
     static BOOST_CONSTEXPR_OR_CONST bool is_specialized = true;
 
@@ -63,6 +65,7 @@
 struct time_traits< boost::chrono::time_point< boost::chrono::system_clock, Duration > >
 {
     typedef time_point_tag tag;
+ typedef system_time_point unit_type;
 
     static BOOST_CONSTEXPR_OR_CONST bool is_specialized = true;
 

Modified: trunk/boost/sync/support/boost_date_time.hpp
==============================================================================
--- trunk/boost/sync/support/boost_date_time.hpp Sun Sep 22 12:06:45 2013 (r85830)
+++ trunk/boost/sync/support/boost_date_time.hpp 2013-09-22 12:54:09 EDT (Sun, 22 Sep 2013) (r85831)
@@ -34,6 +34,7 @@
 struct time_traits< T, typename T::_is_boost_date_time_duration >
 {
     typedef time_duration_tag tag;
+ typedef system_duration unit_type;
 
     static BOOST_CONSTEXPR_OR_CONST bool is_specialized = true;
 
@@ -55,6 +56,7 @@
 struct time_traits< T, typename T::_is_boost_date_time_time_point >
 {
     typedef time_point_tag tag;
+ typedef system_time_point unit_type;
 
     static BOOST_CONSTEXPR_OR_CONST bool is_specialized = true;
 

Modified: trunk/boost/sync/support/posix_time.hpp
==============================================================================
--- trunk/boost/sync/support/posix_time.hpp Sun Sep 22 12:06:45 2013 (r85830)
+++ trunk/boost/sync/support/posix_time.hpp 2013-09-22 12:54:09 EDT (Sun, 22 Sep 2013) (r85831)
@@ -34,6 +34,7 @@
 struct time_traits< struct ::timespec >
 {
     typedef time_point_tag tag;
+ typedef system_time_point unit_type;
 
     static BOOST_CONSTEXPR_OR_CONST bool is_specialized = true;
 

Modified: trunk/boost/sync/support/std_chrono.hpp
==============================================================================
--- trunk/boost/sync/support/std_chrono.hpp Sun Sep 22 12:06:45 2013 (r85830)
+++ trunk/boost/sync/support/std_chrono.hpp 2013-09-22 12:54:09 EDT (Sun, 22 Sep 2013) (r85831)
@@ -34,6 +34,7 @@
 struct time_traits< std::chrono::duration< Rep, Period > >
 {
     typedef time_duration_tag tag;
+ typedef system_duration unit_type;
 
     static BOOST_CONSTEXPR_OR_CONST bool is_specialized = true;
 
@@ -48,12 +49,13 @@
 struct time_traits< std::chrono::time_point< Clock, Duration > >
 {
     typedef time_point_tag tag;
+ typedef chrono_time_point< std::chrono::time_point< Clock, Duration > > unit_type;
 
     static BOOST_CONSTEXPR_OR_CONST bool is_specialized = true;
 
- static chrono_time_point< std::chrono::time_point< Clock, Duration > > to_sync_unit(std::chrono::time_point< Clock, Duration > const& point) BOOST_NOEXCEPT
+ static unit_type to_sync_unit(std::chrono::time_point< Clock, Duration > const& point) BOOST_NOEXCEPT
     {
- return chrono_time_point< std::chrono::time_point< Clock, Duration > >(point);
+ return unit_type(point);
     }
 };
 
@@ -61,6 +63,7 @@
 struct time_traits< std::chrono::time_point< std::chrono::system_clock, Duration > >
 {
     typedef time_point_tag tag;
+ typedef system_time_point unit_type;
 
     static BOOST_CONSTEXPR_OR_CONST bool is_specialized = true;
 

Added: trunk/boost/sync/traits/is_condition_variable_compatible.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/sync/traits/is_condition_variable_compatible.hpp 2013-09-22 12:54:09 EDT (Sun, 22 Sep 2013) (r85831)
@@ -0,0 +1,40 @@
+/*
+ * Copyright Andrey Semashev 2013.
+ * 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)
+ */
+/*!
+ * \file traits/is_condition_variable_compatible.hpp
+ *
+ * \brief This header defines \c is_condition_variable_compatible type trait.
+ */
+
+#ifndef BOOST_SYNC_TRAITS_IS_CONDITION_VARIABLE_COMPATIBLE_HPP_INCLUDED_
+#define BOOST_SYNC_TRAITS_IS_CONDITION_VARIABLE_COMPATIBLE_HPP_INCLUDED_
+
+#include <boost/mpl/bool.hpp>
+#include <boost/sync/detail/config.hpp>
+#include <boost/sync/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+namespace sync {
+
+template< typename Mutex, typename Void = void >
+struct is_condition_variable_compatible : mpl::false_ {};
+
+template< typename Mutex >
+struct is_condition_variable_compatible< Mutex, typename Mutex::_is_condition_variable_compatible > : mpl::false_ {};
+
+} // namespace sync
+
+} // namespace boost
+
+#include <boost/sync/detail/footer.hpp>
+
+#endif // BOOST_SYNC_TRAITS_IS_CONDITION_VARIABLE_COMPATIBLE_HPP_INCLUDED_

Modified: trunk/libs/sync/doc/Jamfile.v2
==============================================================================
--- trunk/libs/sync/doc/Jamfile.v2 Sun Sep 22 12:06:45 2013 (r85830)
+++ trunk/libs/sync/doc/Jamfile.v2 2013-09-22 12:54:09 EDT (Sun, 22 Sep 2013) (r85831)
@@ -59,6 +59,8 @@
                         BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(x)= \\
                         BOOST_DEFAULTED_FUNCTION(x,y)=\"x = default;\" \\
                         BOOST_DELETED_FUNCTION(x)=\"x = delete;\" \\
+ BOOST_SCOPED_ENUM_DECLARE_BEGIN(x)=\"enum class x\" \\
+ BOOST_SCOPED_ENUM_DECLARE_END(x)=\";\" \\
                         BOOST_EXPLICIT_OPERATOR_BOOL()=\"explicit operator bool() const;\" "
         <xsl:param>boost.doxygen.detailns=detail
 # <xsl:param>boost.doxygen.detail=implementation_


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