$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r86428 - in trunk: boost/sync boost/sync/condition_variables boost/sync/detail/condition_variables boost/sync/detail/events boost/sync/detail/mutexes libs/sync/doc libs/sync/src libs/sync/test/run
From: andrey.semashev_at_[hidden]
Date: 2013-10-25 12:35:13
Author: andysem
Date: 2013-10-25 12:35:13 EDT (Fri, 25 Oct 2013)
New Revision: 86428
URL: http://svn.boost.org/trac/boost/changeset/86428
Log:
Implemented notify_all_at_thread_exit, condition_variable_any and manual_reset_event (emulation). Timed mutex tests re-enabled. Added support for compiler-based TLS on non-Windows targets.
Added:
   trunk/boost/sync/condition_variables/condition_variable_any.hpp   (contents, props changed)
   trunk/boost/sync/condition_variables/notify_all_at_thread_exit.hpp   (contents, props changed)
   trunk/boost/sync/detail/condition_variables/condition_variable_any_generic.hpp   (contents, props changed)
   trunk/boost/sync/detail/condition_variables/condition_variable_any_windows.hpp   (contents, props changed)
Text files modified: 
   trunk/boost/sync/condition_variables.hpp                                       |     2                                         
   trunk/boost/sync/condition_variables/condition_variable_any.hpp                |   240 ++++++++++++++++++++++++++++++++++++++++
   trunk/boost/sync/condition_variables/notify_all_at_thread_exit.hpp             |    66 +++++++++++                             
   trunk/boost/sync/detail/condition_variables/condition_variable_any_generic.hpp |   184 ++++++++++++++++++++++++++++++          
   trunk/boost/sync/detail/condition_variables/condition_variable_any_windows.hpp |   162 +++++++++++++++++++++++++++             
   trunk/boost/sync/detail/condition_variables/condition_variable_windows.hpp     |     2                                         
   trunk/boost/sync/detail/events/auto_reset_event_emulation.hpp                  |    14 +-                                      
   trunk/boost/sync/detail/events/manual_reset_event_emulation.hpp                |   204 +++++++++------------------------       
   trunk/boost/sync/detail/mutexes/timed_mutex_posix.hpp                          |     7 +                                       
   trunk/libs/sync/doc/Jamfile.v2                                                 |     1                                         
   trunk/libs/sync/src/tss_manager.hpp                                            |    23 +++                                     
   trunk/libs/sync/src/tss_pthread.cpp                                            |    55 ++++++++                                
   trunk/libs/sync/src/tss_windows.cpp                                            |    15 ++                                      
   trunk/libs/sync/test/run/mutex_test.cpp                                        |    27 +++                                     
   14 files changed, 838 insertions(+), 164 deletions(-)
Modified: trunk/boost/sync/condition_variables.hpp
==============================================================================
--- trunk/boost/sync/condition_variables.hpp	Fri Oct 25 12:35:09 2013	(r86427)
+++ trunk/boost/sync/condition_variables.hpp	2013-10-25 12:35:13 EDT (Fri, 25 Oct 2013)	(r86428)
@@ -21,5 +21,7 @@
 #endif
 
 #include <boost/sync/condition_variables/condition_variable.hpp>
+#include <boost/sync/condition_variables/condition_variable_any.hpp>
+#include <boost/sync/condition_variables/notify_all_at_thread_exit.hpp>
 
 #endif // BOOST_SYNC_CONDITION_VARIABLES_HPP_INCLUDED_
Added: trunk/boost/sync/condition_variables/condition_variable_any.hpp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/boost/sync/condition_variables/condition_variable_any.hpp	2013-10-25 12:35:13 EDT (Fri, 25 Oct 2013)	(r86428)
@@ -0,0 +1,240 @@
+/*
+ * 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_any.hpp
+ *
+ * \brief  This header defines a basic condition variable primitive.
+ */
+
+#ifndef BOOST_SYNC_CONDITION_VARIABLES_CONDITION_VARIABLE_ANY_HPP_INCLUDED_
+#define BOOST_SYNC_CONDITION_VARIABLES_CONDITION_VARIABLE_ANY_HPP_INCLUDED_
+
+#if defined(BOOST_SYNC_DETAIL_DOXYGEN)
+
+namespace boost {
+
+namespace sync {
+
+/*!
+ * \brief The condition variable class
+ */
+class condition_variable_any
+{
+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_any();
+
+    /*!
+     * \brief Destructor
+     *
+     * Destroys the condition variable.
+     *
+     * \pre There are no threads blocked on the object.
+     */
+    ~condition_variable_any();
+
+    condition_variable_any(condition_variable_any const&) = delete;
+    condition_variable_any& operator= (condition_variable_any const&) = delete;
+
+    /*!
+     * \brief Wakes up one thread blocked on the object
+     */
+    void notify_one();
+
+    /*!
+     * \brief Wakes up all threads blocked on the object
+     */
+    void notify_all();
+
+    /*!
+     * \brief Blocks the current thread on the object
+     *
+     * Atomically unlocks the lock and blocks on the object. When unblocked, it locks the lock and returns.
+     * The function can unblock upon another thread calling \c notify_one(), \c notify_all() or spuriously.
+     *
+     * \param lock Lock object. Must be a model of \c BasicLockable.
+     *
+     * \b Throws: An exception in case if the operating system is unable to fulfill the request. The lock is left in the locked state in case of exception.
+     */
+    template< typename Lock >
+    void wait(Lock& 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. Must be a model of \c BasicLockable.
+     * \param pred Condition predicate.
+     *
+     * \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 Lock, typename Predicate >
+    void wait(Lock& lock, Predicate pred);
+
+    /*!
+     * \brief Blocks the current thread on the object until the timeout expires
+     *
+     * Atomically unlocks the lock and blocks on the object. When unblocked, it locks the lock 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. Must be a model of \c BasicLockable.
+     * \param timeout Relative or absolute timeout. If timeout is relative, the time is measured according to the system clock.
+     *
+     * \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 lock 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 Lock, typename Time >
+    bool timed_wait(Lock& 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. Must be a model of \c BasicLockable.
+     * \param timeout Relative or absolute timeout. If timeout is relative, the time is measured according to the system clock.
+     * \param pred Condition predicate.
+     *
+     * \b Throws: An exception in case if the operating system is unable to fulfill the request. The lock 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 Lock, typename Time, typename Predicate >
+    bool timed_wait(Lock& lock, Time const& timeout, Predicate pred);
+
+    /*!
+     * \brief Blocks the current thread on the object until the timeout expires
+     *
+     * Atomically unlocks the lock and blocks on the object. When unblocked, it locks the lock 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. Must be a model of \c BasicLockable.
+     * \param timeout Relative timeout. The time is measured according to the system clock.
+     *
+     * \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 lock 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 Lock, typename Duration >
+    cv_status wait_for(Lock& 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. Must be a model of \c BasicLockable.
+     * \param timeout Relative timeout. The time is measured according to the system clock.
+     * \param pred Condition predicate.
+     *
+     * \b Throws: An exception in case if the operating system is unable to fulfill the request. The lock 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 Lock, typename Duration, typename Predicate >
+    bool wait_for(Lock& lock, Duration const& rel_timeout, Predicate pred);
+
+    /*!
+     * \brief Blocks the current thread on the object until the timeout expires
+     *
+     * Atomically unlocks the lock and blocks on the object. When unblocked, it locks the lock 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. Must be a model of \c BasicLockable.
+     * \param timeout Absolute timeout.
+     *
+     * \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 lock 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 Lock, typename TimePoint >
+    cv_status wait_until(Lock& 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. Must be a model of \c BasicLockable.
+     * \param timeout Absolute timeout.
+     * \param pred Condition predicate.
+     *
+     * \b Throws: An exception in case if the operating system is unable to fulfill the request. The lock 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 Lock, typename TimePoint, typename Predicate >
+    bool wait_until(Lock& lock, TimePoint const& abs_timeout, Predicate pred);
+};
+
+} // 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_WINAPI)
+#include <boost/sync/detail/condition_variables/condition_variable_any_windows.hpp>
+#else
+#include <boost/sync/detail/condition_variables/condition_variable_any_generic.hpp>
+#endif
+
+#endif // defined(BOOST_SYNC_DETAIL_DOXYGEN)
+
+#endif // BOOST_SYNC_CONDITION_VARIABLES_CONDITION_VARIABLE_ANY_HPP_INCLUDED_
Added: trunk/boost/sync/condition_variables/notify_all_at_thread_exit.hpp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/boost/sync/condition_variables/notify_all_at_thread_exit.hpp	2013-10-25 12:35:13 EDT (Fri, 25 Oct 2013)	(r86428)
@@ -0,0 +1,66 @@
+/*
+ * 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/notify_all_at_thread_exit.hpp
+ *
+ * \brief  This header defines the \c notify_all_at_thread_exit function.
+ */
+
+#ifndef BOOST_SYNC_CONDITION_VARIABLES_NOTIFY_ALL_AT_THREAD_EXIT_HPP_INCLUDED_
+#define BOOST_SYNC_CONDITION_VARIABLES_NOTIFY_ALL_AT_THREAD_EXIT_HPP_INCLUDED_
+
+#include <boost/assert.hpp>
+#include <boost/sync/detail/link_config.hpp>
+#include <boost/sync/locks/unique_lock.hpp>
+#include <boost/sync/mutexes/mutex.hpp>
+#include <boost/sync/condition_variables/condition_variable.hpp>
+#include <boost/sync/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+namespace sync {
+
+namespace detail {
+
+//! Adds a notification entry at thread termination
+BOOST_SYNC_API void add_thread_exit_notify_entry(sync::mutex* mtx, sync::condition_variable* cond);
+
+} // namespace detail
+
+/*!
+ * Schedules a notification of the condition variable at the calling thread termination. The notification
+ * shall be performed with the <tt>cond.notify_all()</tt> method shortly before the thread terminates.
+ *
+ * The provided lock must be locked, its ownership is transferred to an external storage until the notification
+ * is performed. If there are threads blocked on the \a cond object, these threads should have used the same
+ * mutex object as the one referred to by the \a lock.
+ *
+ * \param cond Condition variable to perform notification on.
+ * \param lock The lock that owns the mutex, used to block on the condition variable.
+ *
+ * \pre <tt>lock.owns_lock()</tt>
+ * \post <tt>!lock.owns_lock()</tt>
+ */
+inline void notify_all_at_thread_exit(sync::condition_variable& cond, sync::unique_lock< sync::mutex > lock)
+{
+    BOOST_ASSERT(lock.owns_lock());
+    sync::detail::add_thread_exit_notify_entry(lock.mutex(), &cond);
+    lock.release();
+}
+
+} // namespace sync
+
+} // namespace boost
+
+#include <boost/sync/detail/footer.hpp>
+
+#endif // BOOST_SYNC_CONDITION_VARIABLES_NOTIFY_ALL_AT_THREAD_EXIT_HPP_INCLUDED_
Added: trunk/boost/sync/detail/condition_variables/condition_variable_any_generic.hpp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/boost/sync/detail/condition_variables/condition_variable_any_generic.hpp	2013-10-25 12:35:13 EDT (Fri, 25 Oct 2013)	(r86428)
@@ -0,0 +1,184 @@
+/*
+ * 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_any_generic.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_ANY_GENERIC_HPP_INCLUDED_
+#define BOOST_SYNC_DETAIL_CONDITION_VARIABLES_CONDITION_VARIABLE_ANY_GENERIC_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/utility/enable_if.hpp>
+#include <boost/sync/detail/config.hpp>
+#include <boost/sync/detail/time_traits.hpp>
+#include <boost/sync/locks/lock_guard.hpp>
+#include <boost/sync/locks/unique_lock.hpp>
+#include <boost/sync/mutexes/mutex.hpp>
+#include <boost/sync/condition_variables/condition_variable.hpp>
+#include <boost/sync/condition_variables/cv_status.hpp>
+#include <boost/sync/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+namespace sync {
+
+BOOST_SYNC_DETAIL_OPEN_ABI_NAMESPACE {
+
+class condition_variable_any
+{
+private:
+    template< typename Lock >
+    class relocker
+    {
+    private:
+        Lock* m_lock;
+
+    public:
+        relocker() : m_lock(NULL) {}
+
+        ~relocker() BOOST_NOEXCEPT_IF(false)
+        {
+            if (m_lock)
+                m_lock->lock();
+        }
+
+        void unlock(Lock& lock)
+        {
+            lock.unlock();
+            m_lock = &lock;
+        }
+    };
+
+private:
+    sync::mutex m_mutex;
+    sync::condition_variable m_cond;
+
+public:
+#if defined(BOOST_SYNC_DEFINES_MUTEX_CONSTEXPR_CONSTRUCTOR) && defined(BOOST_SYNC_DEFINES_CONDITION_VARIABLE_CONSTEXPR_CONSTRUCTOR)
+#define BOOST_SYNC_DEFINES_CONDITION_VARIABLE_ANY_CONSTEXPR_CONSTRUCTOR
+    BOOST_DEFAULTED_FUNCTION(BOOST_CONSTEXPR condition_variable_any() BOOST_NOEXCEPT, {})
+#else
+    BOOST_DEFAULTED_FUNCTION(condition_variable_any(), {})
+#endif
+
+    void notify_one()
+    {
+        sync::lock_guard< sync::mutex > internal_lock(m_mutex);
+        m_cond.notify_one();
+    }
+
+    void notify_all()
+    {
+        sync::lock_guard< sync::mutex > internal_lock(m_mutex);
+        m_cond.notify_all();
+    }
+
+    template< typename Lock >
+    void wait(Lock& lock)
+    {
+        relocker< Lock > relock_guard;
+        sync::unique_lock< sync::mutex > internal_lock(m_mutex);
+        relock_guard.unlock(lock);
+        m_cond.wait(internal_lock);
+    }
+
+    template< typename Lock, typename Predicate >
+    void wait(Lock& lock, Predicate pred)
+    {
+        while (!pred())
+            this->wait(lock);
+    }
+
+    template< typename Lock, typename Time >
+    typename enable_if_c< sync::detail::time_traits< Time >::is_specialized, bool >::type
+    timed_wait(Lock& lock, Time const& t)
+    {
+        relocker< Lock > relock_guard;
+        sync::unique_lock< sync::mutex > internal_lock(m_mutex);
+        relock_guard.unlock(lock);
+        return m_cond.timed_wait(internal_lock, t);
+    }
+
+    template< typename Lock, typename Time, typename Predicate >
+    typename enable_if_c< sync::detail::time_traits< Time >::is_specialized, bool >::type
+    timed_wait(Lock& lock, Time const& t, Predicate pred)
+    {
+        while (!pred())
+        {
+            if (!this->timed_wait(lock, t))
+                return pred();
+        }
+        return true;
+    }
+
+    template< typename Lock, typename TimePoint >
+    typename detail::enable_if_tag< TimePoint, detail::time_point_tag, sync::cv_status >::type
+    wait_until(Lock& lock, TimePoint const& abs_time)
+    {
+        relocker< Lock > relock_guard;
+        sync::unique_lock< sync::mutex > internal_lock(m_mutex);
+        relock_guard.unlock(lock);
+        return m_cond.wait_until(internal_lock, abs_time);
+    }
+
+    template< typename Lock, typename TimePoint, typename Predicate >
+    typename detail::enable_if_tag< TimePoint, detail::time_point_tag, bool >::type
+    wait_until(Lock& lock, TimePoint const& abs_time, Predicate pred)
+    {
+        while (!pred())
+        {
+            if (this->wait_until(lock, abs_time) != sync::cv_status::no_timeout)
+                return pred();
+        }
+        return true;
+    }
+
+    template< typename Lock, typename Duration >
+    typename detail::enable_if_tag< Duration, detail::time_duration_tag, sync::cv_status >::type
+    wait_for(Lock& lock, Duration const& rel_time)
+    {
+        relocker< Lock > relock_guard;
+        sync::unique_lock< sync::mutex > internal_lock(m_mutex);
+        relock_guard.unlock(lock);
+        return m_cond.wait_for(internal_lock, rel_time);
+    }
+
+    template< typename Lock, typename Duration, typename Predicate >
+    typename detail::enable_if_tag< Duration, detail::time_duration_tag, bool >::type
+    wait_for(Lock& lock, Duration const& rel_time, Predicate pred)
+    {
+        while (!pred())
+        {
+            if (this->wait_for(lock, rel_time) != sync::cv_status::no_timeout)
+                return pred();
+        }
+        return true;
+    }
+
+    BOOST_DELETED_FUNCTION(condition_variable_any(condition_variable_any const&))
+    BOOST_DELETED_FUNCTION(condition_variable_any& operator= (condition_variable_any const&))
+};
+
+} // namespace abi
+
+} // namespace sync
+
+} // namespace boost
+
+#include <boost/sync/detail/footer.hpp>
+
+#endif // BOOST_SYNC_DETAIL_CONDITION_VARIABLES_CONDITION_VARIABLE_ANY_GENERIC_HPP_INCLUDED_
Added: trunk/boost/sync/detail/condition_variables/condition_variable_any_windows.hpp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/boost/sync/detail/condition_variables/condition_variable_any_windows.hpp	2013-10-25 12:35:13 EDT (Fri, 25 Oct 2013)	(r86428)
@@ -0,0 +1,162 @@
+/*
+ * 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_any_windows.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_ANY_WINDOWS_HPP_INCLUDED_
+#define BOOST_SYNC_DETAIL_CONDITION_VARIABLES_CONDITION_VARIABLE_ANY_WINDOWS_HPP_INCLUDED_
+
+#include <boost/utility/enable_if.hpp>
+#include <boost/sync/detail/config.hpp>
+#include <boost/sync/detail/time_traits.hpp>
+#include <boost/sync/detail/time_units.hpp>
+#include <boost/sync/detail/condition_variables/basic_condition_variable_windows.hpp>
+#include <boost/sync/condition_variables/cv_status.hpp>
+#include <boost/sync/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+namespace sync {
+
+BOOST_SYNC_DETAIL_OPEN_ABI_NAMESPACE {
+
+class condition_variable_any
+{
+private:
+    sync::detail::windows::basic_condition_variable m_cond;
+
+public:
+#if !defined(BOOST_NO_CXX11_CONSTEXPR)
+#define BOOST_SYNC_DEFINES_CONDITION_VARIABLE_ANY_CONSTEXPR_CONSTRUCTOR
+#endif
+
+    BOOST_CONSTEXPR condition_variable_any() BOOST_NOEXCEPT : m_cond()
+    {
+    }
+
+    void notify_one() BOOST_NOEXCEPT
+    {
+        m_cond.notify_one();
+    }
+
+    void notify_all() BOOST_NOEXCEPT
+    {
+        m_cond.notify_all();
+    }
+
+    template< typename Lock >
+    void wait(Lock& lock)
+    {
+        m_cond.wait(lock);
+    }
+
+    template< typename Lock, typename Predicate >
+    void wait(Lock& lock, Predicate pred)
+    {
+        while (!pred())
+            m_cond.wait(lock);
+    }
+
+    template< typename Lock, typename Time >
+    typename enable_if_c< sync::detail::time_traits< Time >::is_specialized, bool >::type
+    timed_wait(Lock& lock, Time const& t)
+    {
+        return m_cond.timed_wait(lock, sync::detail::time_traits< Time >::to_sync_unit(t)) == sync::cv_status::no_timeout;
+    }
+
+    template< typename Lock, typename TimePoint, typename Predicate >
+    typename detail::enable_if_tag< TimePoint, detail::time_point_tag, bool >::type
+    timed_wait(Lock& 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 (m_cond.timed_wait(lock, abs_timeout) != sync::cv_status::no_timeout)
+                return pred();
+        }
+        return true;
+    }
+
+    template< typename Lock, typename Duration, typename Predicate >
+    typename detail::enable_if_tag< Duration, detail::time_duration_tag, bool >::type
+    timed_wait(Lock& 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 (m_cond.timed_wait(lock, abs_timeout) != sync::cv_status::no_timeout)
+                return pred();
+        }
+        return true;
+    }
+
+    template< typename Lock, typename TimePoint >
+    typename detail::enable_if_tag< TimePoint, detail::time_point_tag, sync::cv_status >::type
+    wait_until(Lock& lock, TimePoint const& abs_time)
+    {
+        return m_cond.timed_wait(lock, sync::detail::time_traits< TimePoint >::to_sync_unit(abs_time));
+    }
+
+    template< typename Lock, typename TimePoint, typename Predicate >
+    typename detail::enable_if_tag< TimePoint, detail::time_point_tag, bool >::type
+    wait_until(Lock& lock, TimePoint const& abs_time, 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(abs_time);
+        while (!pred())
+        {
+            if (m_cond.timed_wait(lock, abs_timeout) != sync::cv_status::no_timeout)
+                return pred();
+        }
+        return true;
+    }
+
+    template< typename Lock, typename Duration >
+    typename detail::enable_if_tag< Duration, detail::time_duration_tag, sync::cv_status >::type
+    wait_for(Lock& lock, Duration const& rel_time)
+    {
+        return m_cond.timed_wait(lock, sync::detail::time_traits< Duration >::to_sync_unit(rel_time));
+    }
+
+    template< typename Lock, typename Duration, typename Predicate >
+    typename detail::enable_if_tag< Duration, detail::time_duration_tag, bool >::type
+    wait_for(Lock& lock, Duration const& rel_time, Predicate pred)
+    {
+        sync::detail::system_time_point abs_timeout = sync::detail::system_time_point::now() + sync::detail::time_traits< Duration >::to_sync_unit(rel_time);
+        while (!pred())
+        {
+            if (m_cond.timed_wait(lock, abs_timeout) != sync::cv_status::no_timeout)
+                return pred();
+        }
+        return true;
+    }
+
+    BOOST_DELETED_FUNCTION(condition_variable_any(condition_variable_any const&))
+    BOOST_DELETED_FUNCTION(condition_variable_any& operator= (condition_variable_any const&))
+};
+
+} // namespace abi
+
+} // namespace sync
+
+} // namespace boost
+
+#include <boost/sync/detail/footer.hpp>
+
+#endif // BOOST_SYNC_DETAIL_CONDITION_VARIABLES_CONDITION_VARIABLE_ANY_WINDOWS_HPP_INCLUDED_
Modified: trunk/boost/sync/detail/condition_variables/condition_variable_windows.hpp
==============================================================================
--- trunk/boost/sync/detail/condition_variables/condition_variable_windows.hpp	Fri Oct 25 12:35:09 2013	(r86427)
+++ trunk/boost/sync/detail/condition_variables/condition_variable_windows.hpp	2013-10-25 12:35:13 EDT (Fri, 25 Oct 2013)	(r86428)
@@ -164,7 +164,7 @@
     BOOST_DELETED_FUNCTION(condition_variable& operator= (condition_variable const&))
 };
 
-} // namespace posix
+} // namespace abi
 
 } // namespace sync
 
Modified: trunk/boost/sync/detail/events/auto_reset_event_emulation.hpp
==============================================================================
--- trunk/boost/sync/detail/events/auto_reset_event_emulation.hpp	Fri Oct 25 12:35:09 2013	(r86427)
+++ trunk/boost/sync/detail/events/auto_reset_event_emulation.hpp	2013-10-25 12:35:13 EDT (Fri, 25 Oct 2013)	(r86428)
@@ -1,4 +1,4 @@
-// event.hpp, condition variable emulation
+// auto_reset_event_emulation.hpp, event emulation
 //
 // Copyright (C) 2013 Tim Blechmann
 // Copyright (C) 2013 Andrey Semashev
@@ -23,7 +23,7 @@
 #pragma once
 #endif
 
-#define BOOST_SYNC_EVENT_EMULATED
+#define BOOST_SYNC_AUTO_RESET_EVENT_EMULATED
 
 namespace boost {
 
@@ -34,20 +34,22 @@
 class auto_reset_event
 {
     BOOST_DELETED_FUNCTION(auto_reset_event(auto_reset_event const&));
-    BOOST_DELETED_FUNCTION(auto_reset_event& operator=(auto_reset_event const&));
+    BOOST_DELETED_FUNCTION(auto_reset_event& operator= (auto_reset_event const&));
 
 public:
-    auto_reset_event() BOOST_NOEXCEPT : m_is_set(false)
+    auto_reset_event() : m_is_set(false)
     {
     }
 
     void post()
     {
         sync::lock_guard< sync::mutex > lock(m_mutex);
-        bool already_signaled = m_is_set;
-        m_is_set = true;
+        const bool already_signaled = m_is_set;
         if (!already_signaled)
+        {
+            m_is_set = true;
             m_cond.notify_one();
+        }
     }
 
     void wait()
Modified: trunk/boost/sync/detail/events/manual_reset_event_emulation.hpp
==============================================================================
--- trunk/boost/sync/detail/events/manual_reset_event_emulation.hpp	Fri Oct 25 12:35:09 2013	(r86427)
+++ trunk/boost/sync/detail/events/manual_reset_event_emulation.hpp	2013-10-25 12:35:13 EDT (Fri, 25 Oct 2013)	(r86428)
@@ -1,209 +1,119 @@
-// event.hpp, condition variable emulation
+// manual_reset_event_emulation.hpp, event emulation
 //
 // Copyright (C) 2013 Tim Blechmann
+// Copyright (C) 2013 Andrey Semashev
 //
 // 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_SYNC_DETAIL_EVENT_EVENT_EMULATION_HPP_INCLUDED_
-#define BOOST_SYNC_DETAIL_EVENT_EVENT_EMULATION_HPP_INCLUDED_
-
-#include <boost/sync/semaphore.hpp>
-
-// we use the semaphore implementation if we have native semaphores
-#ifndef BOOST_SYNC_SEMAPHORE_EMULATED
-#include <boost/sync/detail/event/event_autoreset_semaphore.hpp>
-#endif
-
-
-#include <boost/thread/condition_variable.hpp>
-#include <boost/thread/shared_mutex.hpp>
-#include <boost/thread/locks.hpp>
+#ifndef BOOST_SYNC_DETAIL_EVENTS_MANUAL_RESET_EVENT_EMULATION_HPP_INCLUDED_
+#define BOOST_SYNC_DETAIL_EVENTS_MANUAL_RESET_EVENT_EMULATION_HPP_INCLUDED_
 
+#include <boost/utility/enable_if.hpp>
 #include <boost/sync/detail/config.hpp>
-//#include <boost/sync/locks/lock_guard.hpp>
-//#include <boost/sync/locks/unique_lock.hpp>
+#include <boost/sync/detail/time_traits.hpp>
+#include <boost/sync/locks/lock_guard.hpp>
+#include <boost/sync/locks/unique_lock.hpp>
+#include <boost/sync/mutexes/mutex.hpp>
+#include <boost/sync/condition_variables/condition_variable.hpp>
 #include <boost/sync/detail/header.hpp>
 
-#define BOOST_SYNC_EVENT_EMULATED
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#define BOOST_SYNC_MANUAL_RESET_EVENT_EMULATED
 
 namespace boost {
-namespace sync {
-BOOST_SYNC_DETAIL_OPEN_ABI_NAMESPACE {
 
+namespace sync {
 
-#ifdef BOOST_SYNC_SEMAPHORE_EMULATED
+BOOST_SYNC_DETAIL_OPEN_ABI_NAMESPACE {
 
-class auto_reset_event
+class manual_reset_event
 {
-    BOOST_DELETED_FUNCTION(auto_reset_event(auto_reset_event const&));
-    BOOST_DELETED_FUNCTION(auto_reset_event& operator=(auto_reset_event const&));
+    BOOST_DELETED_FUNCTION(manual_reset_event(manual_reset_event const&));
+    BOOST_DELETED_FUNCTION(manual_reset_event& operator= (manual_reset_event const&));
 
 public:
-    auto_reset_event() BOOST_NOEXCEPT :
-        m_is_set(false)
-    {}
-
-    void post()
-    {
-        unique_lock<upgrade_mutex> lock(m_mutex);
-        bool already_signaled = m_is_set;
-        m_is_set = true;
-        if (!already_signaled)
-            m_cond.notify_one();
-    }
-
-    void wait()
+    manual_reset_event() : m_is_set(false)
     {
-        upgrade_lock<upgrade_mutex> lock(m_mutex);
-
-        while (!m_is_set)
-            m_cond.wait(lock);
-
-        upgrade_to_unique_lock<upgrade_mutex> unique_lock(lock);
-        m_is_set = false;
-    }
-
-    void reset()
-    {
-        lock_guard<upgrade_mutex> lock(m_mutex);
-        m_is_set = false;
     }
 
-    bool try_wait()
+    void set()
     {
-        lock_guard<upgrade_mutex> lock(m_mutex);
-        const bool res = m_is_set;
-        if (res)
-            m_is_set = false;
-        return res;
-    }
-
-    template <class Duration>
-    bool try_wait_for(const Duration & duration)
-    {
-        upgrade_lock<upgrade_mutex> lock(m_mutex);
-
-        while (!m_is_set) {
-            if (m_cond.wait_for(lock, duration) == cv_status::timeout) {
-                if (!m_is_set)
-                    return false;
-                break;
-            }
+        sync::lock_guard< sync::mutex > lock(m_mutex);
+        const bool already_signaled = m_is_set;
+        if (!already_signaled)
+        {
+            m_is_set = true;
+            m_cond.notify_all();
         }
-
-        upgrade_to_unique_lock<upgrade_mutex> unique_lock(lock);
-        m_is_set = false;
-        return true;
     }
 
-    template <typename TimePoint>
-    bool try_wait_until(const TimePoint & timeout)
+    void reset()
     {
-        upgrade_lock<upgrade_mutex> lock(m_mutex);
-
-        while (!m_is_set) {
-            if (m_cond.wait_until(lock, timeout) == cv_status::timeout) {
-                if (!m_is_set)
-                    return false;
-                break;
-            }
-        }
-
-        upgrade_to_unique_lock<upgrade_mutex> unique_lock(lock);
+        sync::lock_guard< sync::mutex > lock(m_mutex);
         m_is_set = false;
-        return true;
-    }
-
-private:
-    bool m_is_set;
-    upgrade_mutex m_mutex;
-    condition_variable_any m_cond;
-};
-
-#endif
-
-class manual_reset_event
-{
-    BOOST_DELETED_FUNCTION(manual_reset_event(manual_reset_event const&));
-    BOOST_DELETED_FUNCTION(manual_reset_event& operator=(manual_reset_event const&));
-
-public:
-    manual_reset_event() BOOST_NOEXCEPT :
-        m_is_set(false)
-    {}
-
-    void post()
-    {
-        unique_lock<upgrade_mutex> lock(m_mutex);
-        bool already_signaled = m_is_set;
-        m_is_set = true;
-        m_cond.notify_all();
     }
 
     void wait()
     {
-        upgrade_lock<upgrade_mutex> lock(m_mutex);
+        sync::unique_lock< sync::mutex > lock(m_mutex);
 
         while (!m_is_set)
             m_cond.wait(lock);
     }
 
-    void reset()
-    {
-        lock_guard<upgrade_mutex> lock(m_mutex);
-        m_is_set = false;
-    }
-
     bool try_wait()
     {
-        lock_guard<upgrade_mutex> lock(m_mutex);
+        sync::lock_guard< sync::mutex > lock(m_mutex);
         return m_is_set;
     }
 
-    template <typename Duration>
-    bool try_wait_for(const Duration & duration)
+    template< typename Time >
+    typename enable_if_c< sync::detail::time_traits< Time >::is_specialized, bool >::type timed_wait(Time const& timeout)
     {
-        upgrade_lock<upgrade_mutex> lock(m_mutex);
-
-        while (!m_is_set) {
-            if (m_cond.wait_for(lock, duration) == cv_status::timeout) {
+        sync::unique_lock< sync::mutex > lock(m_mutex);
+        while (!m_is_set)
+        {
+            if (!m_cond.timed_wait(lock, timeout))
+            {
                 if (!m_is_set)
                     return false;
-                break;
+                else
+                    break;
             }
         }
 
         return true;
     }
 
-    template <typename TimePoint>
-    bool try_wait_until(const TimePoint & timeout)
+    template< typename Duration >
+    typename enable_if< detail::is_time_tag_of< Duration, detail::time_duration_tag >, bool >::type wait_for(Duration const& duration)
     {
-        upgrade_lock<upgrade_mutex> lock(m_mutex);
-
-        while (!m_is_set) {
-            if (m_cond.wait_until(lock, timeout) == cv_status::timeout) {
-                if (!m_is_set)
-                    return false;
-                break;
-            }
-        }
+        return timed_wait(duration);
+    }
 
-        return true;
+    template< typename TimePoint >
+    typename enable_if< detail::is_time_tag_of< TimePoint, detail::time_point_tag >, bool >::type wait_until(TimePoint const& abs_time)
+    {
+        return timed_wait(abs_time);
     }
 
 private:
+    sync::mutex m_mutex;
+    sync::condition_variable m_cond;
     bool m_is_set;
-    upgrade_mutex m_mutex;
-    condition_variable_any m_cond;
 };
 
-}
-}
-}
+} // namespace abi
+
+} // namespace sync
+
+} // namespace boost
 
 #include <boost/sync/detail/footer.hpp>
 
-#endif // BOOST_SYNC_DETAIL_EVENT_EVENT_EMULATION_HPP_INCLUDED_
+#endif // BOOST_SYNC_DETAIL_EVENTS_MANUAL_RESET_EVENT_EMULATION_HPP_INCLUDED_
Modified: trunk/boost/sync/detail/mutexes/timed_mutex_posix.hpp
==============================================================================
--- trunk/boost/sync/detail/mutexes/timed_mutex_posix.hpp	Fri Oct 25 12:35:09 2013	(r86427)
+++ trunk/boost/sync/detail/mutexes/timed_mutex_posix.hpp	2013-10-25 12:35:13 EDT (Fri, 25 Oct 2013)	(r86428)
@@ -37,7 +37,9 @@
 #pragma once
 #endif
 
+#if defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK)
 #define BOOST_SYNC_DEFINES_TIMED_MUTEX_NATIVE_HANDLE
+#endif
 
 namespace boost {
 
@@ -51,8 +53,9 @@
 #if defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK)
     typedef void _is_condition_variable_compatible;
 #endif
-
+#if defined(BOOST_SYNC_DEFINES_TIMED_MUTEX_NATIVE_HANDLE)
     typedef pthread_mutex_t* native_handle_type;
+#endif
 
 private:
     pthread_mutex_t m_mutex;
@@ -186,10 +189,12 @@
         return priv_timed_lock(sync::detail::time_traits< TimePoint >::to_sync_unit(abs_time));
     }
 
+#if defined(BOOST_SYNC_DEFINES_TIMED_MUTEX_NATIVE_HANDLE)
     native_handle_type native_handle() BOOST_NOEXCEPT
     {
         return &m_mutex;
     }
+#endif
 
     BOOST_DELETED_FUNCTION(timed_mutex(timed_mutex const&))
     BOOST_DELETED_FUNCTION(timed_mutex& operator= (timed_mutex const&))
Modified: trunk/libs/sync/doc/Jamfile.v2
==============================================================================
--- trunk/libs/sync/doc/Jamfile.v2	Fri Oct 25 12:35:09 2013	(r86427)
+++ trunk/libs/sync/doc/Jamfile.v2	2013-10-25 12:35:13 EDT (Fri, 25 Oct 2013)	(r86428)
@@ -44,6 +44,7 @@
 #        <doxygen:param>"INCLUDE_PATH=../../.."
 #        <doxygen:param>EXCLUDE_SYMBOLS="aux aux::*"
         <doxygen:param>"PREDEFINED=BOOST_SYNC_DETAIL_DOXYGEN \\
+                        BOOST_SYNC_API= \\
                         BOOST_SYMBOL_VISIBLE= \\
                         BOOST_FORCEINLINE=inline \\
                         BOOST_STATIC_ASSERT(x)= \\
Modified: trunk/libs/sync/src/tss_manager.hpp
==============================================================================
--- trunk/libs/sync/src/tss_manager.hpp	Fri Oct 25 12:35:09 2013	(r86427)
+++ trunk/libs/sync/src/tss_manager.hpp	2013-10-25 12:35:13 EDT (Fri, 25 Oct 2013)	(r86428)
@@ -25,6 +25,7 @@
 #include <boost/sync/locks/lock_guard.hpp>
 #include <boost/sync/locks/unique_lock.hpp>
 #include <boost/sync/mutexes/mutex.hpp>
+#include <boost/sync/condition_variables/condition_variable.hpp>
 #include <boost/sync/detail/tss.hpp>
 #include <boost/sync/detail/header.hpp>
 
@@ -58,9 +59,16 @@
             void* context;
         };
 
+        struct notify_at_exit_entry
+        {
+            sync::mutex* mtx;
+            sync::condition_variable* cond;
+        };
+
     private:
         std::vector< void* > m_storage;
         std::vector< at_exit_entry > m_at_exit_functions;
+        std::vector< notify_at_exit_entry > m_notify_at_exit;
 
     public:
         void* get_value(thread_specific_key key) const BOOST_NOEXCEPT
@@ -85,6 +93,14 @@
             entry.context = context;
             m_at_exit_functions.push_back(entry);
         }
+
+        void add_notify_at_exit_entry(sync::mutex* mtx, sync::condition_variable* cond)
+        {
+            notify_at_exit_entry entry;
+            entry.mtx = mtx;
+            entry.cond = cond;
+            m_notify_at_exit.push_back(entry);
+        }
     };
 
 private:
@@ -162,6 +178,13 @@
             }
         }
 
+        // Notify about thread termination. This must be performed last, after all TLS variables are destroyed.
+        for (std::vector< thread_context::notify_at_exit_entry >::const_iterator it = p->m_notify_at_exit.begin(), end = p->m_notify_at_exit.end(); it != end; ++it)
+        {
+            it->mtx->unlock();
+            it->cond->notify_all();
+        }
+
         // Destroy the context
         {
             sync::lock_guard< mutex_type > lock(m_mutex);
Modified: trunk/libs/sync/src/tss_pthread.cpp
==============================================================================
--- trunk/libs/sync/src/tss_pthread.cpp	Fri Oct 25 12:35:09 2013	(r86427)
+++ trunk/libs/sync/src/tss_pthread.cpp	2013-10-25 12:35:13 EDT (Fri, 25 Oct 2013)	(r86428)
@@ -21,6 +21,7 @@
 #include <cstdlib>
 #include <pthread.h>
 #include <boost/sync/detail/tss.hpp>
+#include <boost/sync/condition_variables/notify_all_at_thread_exit.hpp>
 #include "tss_manager.hpp"
 #include <boost/sync/detail/header.hpp>
 
@@ -34,7 +35,11 @@
 
 static pthread_once_t init_tss_once_flag = PTHREAD_ONCE_INIT;
 static tss_manager* tss_mgr = NULL;
+#if defined(BOOST_SYNC_DETAIL_TLS)
+static BOOST_SYNC_DETAIL_TLS tss_manager::thread_context* tss_context = NULL;
+#else
 static pthread_key_t tss_key;
+#endif
 
 extern "C" {
 
@@ -57,23 +62,63 @@
         std::abort();
     }
 
+#if !defined(BOOST_SYNC_DETAIL_TLS)
     if (pthread_key_create(&tss_key, &tss_cleanup) != 0)
         std::abort();
+#endif
 }
 
 } // extern "C"
 
+#if defined(BOOST_SYNC_DETAIL_TLS)
+
+BOOST_FORCEINLINE tss_manager::thread_context* get_thread_context() BOOST_NOEXCEPT
+{
+    return tss_context;
+}
+BOOST_FORCEINLINE void set_thread_context(tss_manager::thread_context* p) BOOST_NOEXCEPT
+{
+    tss_context = p;
+}
+
+#else // defined(BOOST_SYNC_DETAIL_TLS)
+
+BOOST_FORCEINLINE tss_manager::thread_context* get_thread_context() BOOST_NOEXCEPT
+{
+    return static_cast< tss_manager::thread_context* >(pthread_getspecific(tss_key));
+}
+BOOST_FORCEINLINE void set_thread_context(tss_manager::thread_context* p) BOOST_NOEXCEPT
+{
+    pthread_setspecific(tss_key, p);
+}
+
+#endif // defined(BOOST_SYNC_DETAIL_TLS)
+
 } // namespace
 
+BOOST_SYNC_API void add_thread_exit_notify_entry(sync::mutex* mtx, sync::condition_variable* cond)
+{
+    pthread_once(&init_tss_once_flag, &init_tss);
+    tss_manager::thread_context* ctx = get_thread_context();
+
+    if (!ctx)
+    {
+        ctx = tss_mgr->create_thread_context();
+        set_thread_context(ctx);
+    }
+
+    ctx->add_notify_at_exit_entry(mtx, cond);
+}
+
 BOOST_SYNC_API void add_thread_exit_callback(at_thread_exit_callback callback, void* context)
 {
     pthread_once(&init_tss_once_flag, &init_tss);
-    tss_manager::thread_context* ctx = static_cast< tss_manager::thread_context* >(pthread_getspecific(tss_key));
+    tss_manager::thread_context* ctx = get_thread_context();
 
     if (!ctx)
     {
         ctx = tss_mgr->create_thread_context();
-        pthread_setspecific(tss_key, ctx);
+        set_thread_context(ctx);
     }
 
     ctx->add_at_exit_entry(callback, context);
@@ -99,7 +144,7 @@
 
 BOOST_SYNC_API void* get_thread_specific(thread_specific_key key)
 {
-    tss_manager::thread_context* ctx = static_cast< tss_manager::thread_context* >(pthread_getspecific(tss_key));
+    tss_manager::thread_context* ctx = get_thread_context();
     if (ctx)
         return ctx->get_value(key);
     return NULL;
@@ -107,12 +152,12 @@
 
 BOOST_SYNC_API void set_thread_specific(thread_specific_key key, void* p)
 {
-    tss_manager::thread_context* ctx = static_cast< tss_manager::thread_context* >(pthread_getspecific(tss_key));
+    tss_manager::thread_context* ctx = get_thread_context();
 
     if (!ctx)
     {
         ctx = tss_mgr->create_thread_context();
-        pthread_setspecific(tss_key, ctx);
+        set_thread_context(ctx);
     }
 
     ctx->set_value(key, p);
Modified: trunk/libs/sync/src/tss_windows.cpp
==============================================================================
--- trunk/libs/sync/src/tss_windows.cpp	Fri Oct 25 12:35:09 2013	(r86427)
+++ trunk/libs/sync/src/tss_windows.cpp	2013-10-25 12:35:13 EDT (Fri, 25 Oct 2013)	(r86428)
@@ -21,6 +21,7 @@
 #include <cstdlib>
 #include <boost/sync/detail/interlocked.hpp>
 #include <boost/sync/detail/tss.hpp>
+#include <boost/sync/condition_variables/notify_all_at_thread_exit.hpp>
 #include "tss_manager.hpp"
 #include "tss_windows_hooks.hpp"
 #include <windows.h>
@@ -165,6 +166,20 @@
 
 } // namespace windows
 
+BOOST_SYNC_API void add_thread_exit_notify_entry(sync::mutex* mtx, sync::condition_variable* cond)
+{
+    init_tss_once();
+    tss_manager::thread_context* ctx = get_thread_context();
+
+    if (!ctx)
+    {
+        ctx = tss_mgr->create_thread_context();
+        set_thread_context(ctx);
+    }
+
+    ctx->add_notify_at_exit_entry(mtx, cond);
+}
+
 BOOST_SYNC_API void add_thread_exit_callback(at_thread_exit_callback callback, void* context)
 {
     init_tss_once();
Modified: trunk/libs/sync/test/run/mutex_test.cpp
==============================================================================
--- trunk/libs/sync/test/run/mutex_test.cpp	Fri Oct 25 12:35:09 2013	(r86427)
+++ trunk/libs/sync/test/run/mutex_test.cpp	2013-10-25 12:35:13 EDT (Fri, 25 Oct 2013)	(r86428)
@@ -7,9 +7,12 @@
 #include <boost/test/unit_test.hpp>
 
 #include <boost/bind.hpp>
+#include <boost/mpl/if.hpp>
 #include <boost/sync/mutexes.hpp>
 #include <boost/sync/locks.hpp>
 #include <boost/sync/condition_variables/condition_variable.hpp>
+#include <boost/sync/condition_variables/condition_variable_any.hpp>
+#include <boost/sync/traits/is_condition_variable_compatible.hpp>
 #include <boost/sync/support/boost_date_time.hpp>
 #include <boost/thread/thread.hpp>
 #include <boost/thread/thread_time.hpp>
@@ -21,12 +24,17 @@
 struct test_lock
 {
     typedef M mutex_type;
+    typedef typename boost::mpl::if_<
+        boost::sync::is_condition_variable_compatible< mutex_type >,
+        boost::sync::condition_variable,
+        boost::sync::condition_variable_any
+    >::type condition_variable_type;
     typedef boost::sync::unique_lock< mutex_type > lock_type;
 
     void operator()() const
     {
         mutex_type mutex;
-        boost::sync::condition_variable condition;
+        condition_variable_type condition;
 
         // Test the lock's constructors.
         {
@@ -57,12 +65,17 @@
 struct test_trylock
 {
     typedef M mutex_type;
+    typedef typename boost::mpl::if_<
+        boost::sync::is_condition_variable_compatible< mutex_type >,
+        boost::sync::condition_variable,
+        boost::sync::condition_variable_any
+    >::type condition_variable_type;
     typedef boost::sync::unique_lock< mutex_type > lock_type;
 
     void operator()()
     {
         mutex_type mutex;
-        boost::sync::condition_variable condition;
+        condition_variable_type condition;
 
         // Test the lock's constructors.
         {
@@ -182,6 +195,11 @@
 struct test_timedlock
 {
     typedef M mutex_type;
+    typedef typename boost::mpl::if_<
+        boost::sync::is_condition_variable_compatible< mutex_type >,
+        boost::sync::condition_variable,
+        boost::sync::condition_variable_any
+    >::type condition_variable_type;
     typedef boost::sync::unique_lock< mutex_type > lock_type;
     typedef boost::sync::unique_lock< mutex_type > timed_lock_type;
 
@@ -195,7 +213,7 @@
         test_lock_times_out_if_other_thread_has_lock<mutex_type>()();
 
         mutex_type mutex;
-        boost::sync::condition_variable condition;
+        condition_variable_type condition;
 
         // Test the lock's constructors.
         {
@@ -284,7 +302,7 @@
     timed_test(&do_test_try_mutex, 3);
 }
 
-/*
+
 void do_test_timed_mutex()
 {
     test_lock<boost::sync::timed_mutex>()();
@@ -297,6 +315,7 @@
     timed_test(&do_test_timed_mutex, 3);
 }
 
+/*
 void do_test_recursive_mutex()
 {
     test_lock<boost::recursive_mutex>()();