Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r86007 - in trunk/boost: detail/winapi sync sync/detail sync/detail/condition_variables sync/detail/mutexes sync/locks
From: andrey.semashev_at_[hidden]
Date: 2013-09-29 12:42:24


Author: andysem
Date: 2013-09-29 12:42:24 EDT (Sun, 29 Sep 2013)
New Revision: 86007
URL: http://svn.boost.org/trac/boost/changeset/86007

Log:
Finished POSIX condition_variable, working on Windows.

Added:
   trunk/boost/sync/detail/auto_handle.hpp (contents, props changed)
   trunk/boost/sync/detail/condition_variables/basic_condition_variable_windows.hpp (contents, props changed)
   trunk/boost/sync/detail/condition_variables/condition_variable_windows.hpp (contents, props changed)
   trunk/boost/sync/detail/windows_primitives.hpp (contents, props changed)
   trunk/boost/sync/locks/unlock_guard.hpp (contents, props changed)
   trunk/boost/sync/locks/unlock_guard_fwd.hpp (contents, props changed)
Text files modified:
   trunk/boost/detail/winapi/handles.hpp | 14 +
   trunk/boost/sync/detail/auto_handle.hpp | 123 ++++++++++++++
   trunk/boost/sync/detail/condition_variables/basic_condition_variable_windows.hpp | 339 ++++++++++++++++++++++++++++++++++++++++
   trunk/boost/sync/detail/condition_variables/condition_variable_posix.hpp | 124 ++++++++-----
   trunk/boost/sync/detail/condition_variables/condition_variable_windows.hpp | 240 ++++++++++++++++++++++++++++
   trunk/boost/sync/detail/mutexes/mutex_posix.hpp | 4
   trunk/boost/sync/detail/mutexes/mutex_windows.hpp | 4
   trunk/boost/sync/detail/mutexes/timed_mutex_posix.hpp | 5
   trunk/boost/sync/detail/mutexes/timed_mutex_windows.hpp | 4
   trunk/boost/sync/detail/time_traits.hpp | 7
   trunk/boost/sync/detail/windows_primitives.hpp | 65 +++++++
   trunk/boost/sync/locks.hpp | 1
   trunk/boost/sync/locks/unlock_guard.hpp | 65 +++++++
   trunk/boost/sync/locks/unlock_guard_fwd.hpp | 41 ++++
   14 files changed, 981 insertions(+), 55 deletions(-)

Modified: trunk/boost/detail/winapi/handles.hpp
==============================================================================
--- trunk/boost/detail/winapi/handles.hpp Sun Sep 29 12:14:57 2013 (r86006)
+++ trunk/boost/detail/winapi/handles.hpp 2013-09-29 12:42:24 EDT (Sun, 29 Sep 2013) (r86007)
@@ -24,14 +24,20 @@
 #if defined( BOOST_USE_WINDOWS_H )
     using ::CloseHandle;
     using ::DuplicateHandle;
+
+ const DWORD_ duplicate_close_source = DUPLICATE_CLOSE_SOURCE;
+ const DWORD_ duplicate_same_access = DUPLICATE_SAME_ACCESS;
+ const HANDLE_ invalid_handle_value = INVALID_HANDLE_VALUE;
 #else
-extern "C" {
- __declspec(dllimport) int __stdcall
+extern "C" {
+ __declspec(dllimport) int __stdcall
         CloseHandle(void*);
- __declspec(dllimport) int __stdcall
+ __declspec(dllimport) int __stdcall
         DuplicateHandle(void*,void*,void*,void**,unsigned long,int,unsigned long);
 }
-
+ const DWORD_ duplicate_close_source = 1;
+ const DWORD_ duplicate_same_access = 2;
+ const HANDLE_ invalid_handle_value = (HANDLE_)(-1);
 #endif
 }
 }

Added: trunk/boost/sync/detail/auto_handle.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/sync/detail/auto_handle.hpp 2013-09-29 12:42:24 EDT (Sun, 29 Sep 2013) (r86007)
@@ -0,0 +1,123 @@
+/*
+ * 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 2005-2007 Anthony Williams
+ * (C) Copyright 2007 David Deakins
+ * (C) Copyright 2013 Andrey Semashev
+ */
+/*!
+ * \file auto_handle.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.
+ *
+ * This header contains a scope guard to automatically release Windows handles.
+ */
+
+#ifndef BOOST_SYNC_DETAIL_AUTO_HANDLE_HPP_INCLUDED_
+#define BOOST_SYNC_DETAIL_AUTO_HANDLE_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/assert.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/detail/winapi/handles.hpp>
+#include <boost/detail/winapi/GetLastError.hpp>
+#include <boost/detail/winapi/GetCurrentProcess.hpp>
+#include <boost/sync/detail/config.hpp>
+#include <boost/sync/exceptions/resource_error.hpp>
+#include <boost/sync/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+namespace sync {
+
+namespace detail {
+
+namespace windows {
+
+class auto_handle
+{
+private:
+ boost::detail::winapi::HANDLE_ m_handle;
+
+public:
+ BOOST_CONSTEXPR explicit auto_handle(boost::detail::winapi::HANDLE_ h = NULL) BOOST_NOEXCEPT : m_handle(h)
+ {
+ }
+
+ ~auto_handle()
+ {
+ reset();
+ }
+
+ void reset(boost::detail::winapi::HANDLE_ h = NULL) BOOST_NOEXCEPT
+ {
+ if (m_handle && m_handle != boost::detail::winapi::invalid_handle_value)
+ {
+ BOOST_VERIFY(boost::detail::winapi::CloseHandle(m_handle));
+ }
+ m_handle = h;
+ }
+
+ boost::detail::winapi::HANDLE_ get() const BOOST_NOEXCEPT
+ {
+ return m_handle;
+ }
+
+ operator boost::detail::winapi::HANDLE_ () const BOOST_NOEXCEPT
+ {
+ return m_handle;
+ }
+
+ bool operator! () const BOOST_NOEXCEPT
+ {
+ return !m_handle;
+ }
+
+ boost::detail::winapi::HANDLE_ release() BOOST_NOEXCEPT
+ {
+ const boost::detail::winapi::HANDLE_ h = m_handle;
+ m_handle = NULL;
+ return h;
+ }
+
+ boost::detail::winapi::HANDLE_ duplicate() const
+ {
+ const boost::detail::winapi::HANDLE_ current_process = boost::detail::winapi::GetCurrentProcess();
+ boost::detail::winapi::HANDLE_ new_handle = NULL;
+ if (boost::detail::winapi::DuplicateHandle(current_process, m_handle, current_process, &new_handle, 0, false, boost::detail::winapi::duplicate_same_access) == 0)
+ {
+ const boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError();
+ BOOST_THROW_EXCEPTION(resource_error(err, "boost::sync: failed to duplicate a handle"));
+ }
+ return new_handle;
+ }
+
+ void swap(auto_handle& that)
+ {
+ const boost::detail::winapi::HANDLE_ h = m_handle;
+ m_handle = that.m_handle;
+ that.m_handle = h;
+ }
+
+ BOOST_DELETED_FUNCTION(auto_handle(auto_handle const&))
+ BOOST_DELETED_FUNCTION(auto_handle& operator= (auto_handle const&))
+};
+
+} // namespace windows
+
+} // namespace detail
+
+} // namespace sync
+
+} // namespace boost
+
+#include <boost/sync/detail/footer.hpp>
+
+#endif // BOOST_SYNC_DETAIL_AUTO_HANDLE_HPP_INCLUDED_

Added: trunk/boost/sync/detail/condition_variables/basic_condition_variable_windows.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/sync/detail/condition_variables/basic_condition_variable_windows.hpp 2013-09-29 12:42:24 EDT (Sun, 29 Sep 2013) (r86007)
@@ -0,0 +1,339 @@
+/*
+ * 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/basic_condition_variable_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_BASIC_CONDITION_VARIABLE_WINDOWS_HPP_INCLUDED_
+#define BOOST_SYNC_DETAIL_CONDITION_VARIABLES_BASIC_CONDITION_VARIABLE_WINDOWS_HPP_INCLUDED_
+
+#include <limits.h>
+#include <cstddef>
+#include <vector>
+#include <algorithm>
+#include <boost/assert.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/smart_ptr/intrusive_ptr.hpp>
+#include <boost/smart_ptr/intrusive_ref_counter.hpp>
+#include <boost/detail/winapi/synchronization.hpp>
+#include <boost/sync/detail/config.hpp>
+#include <boost/sync/locks/unique_lock_fwd.hpp>
+#include <boost/sync/exceptions/runtime_exception.hpp>
+#include <boost/sync/exceptions/resource_error.hpp>
+#include <boost/sync/detail/time_traits.hpp>
+#include <boost/sync/detail/time_units.hpp>
+#include <boost/sync/detail/interlocked.hpp>
+#include <boost/sync/detail/auto_handle.hpp>
+#include <boost/sync/detail/windows_primitives.hpp>
+#include <boost/sync/locks/lock_guard.hpp>
+#include <boost/sync/mutexes/mutex.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 {
+
+namespace detail {
+
+namespace windows {
+
+class cv_list_entry :
+ public intrusive_ref_counter< cv_list_entry >
+{
+private:
+ auto_handle m_semaphore;
+ auto_handle m_wake_sem;
+ long m_waiters;
+ bool m_notified;
+
+public:
+ explicit cv_list_entry(auto_handle const& wake_sem):
+ m_semaphore(create_anonymous_semaphore(0, LONG_MAX)),
+ m_wake_sem(wake_sem.duplicate()),
+ m_waiters(1),
+ m_notified(false)
+ {
+ if (!m_semaphore)
+ BOOST_THROW_EXCEPTION(resource_error("boost::sync::condition_variable: failed to create a semaphore"));
+ }
+
+ static bool no_waiters(boost::intrusive_ptr< cv_list_entry > const& entry)
+ {
+ return interlocked_read_acquire(&entry->m_waiters) == 0;
+ }
+
+ void add_waiter()
+ {
+ BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&m_waiters, 1);
+ }
+
+ void remove_waiter()
+ {
+ BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&m_waiters, -1);
+ }
+
+ void release(unsigned count_to_release)
+ {
+ m_notified = true;
+ boost::detail::winapi::ReleaseSemaphore(m_semaphore, count_to_release, 0);
+ }
+
+ void release_waiters()
+ {
+ release(interlocked_read_acquire(&m_waiters));
+ }
+
+ bool is_notified() const
+ {
+ return m_notified;
+ }
+
+ void wait()
+ {
+ const boost::detail::winapi::DWORD_ res = boost::detail::winapi::WaitForSingleObject(m_semaphore, boost::detail::winapi::infinite);
+ if (res != boost::detail::winapi::wait_object_0)
+ BOOST_THROW_EXCEPTION(runtime_exception(res, "boost::sync::condition_variable wait failed in WaitForSingleObject"));
+ }
+
+ bool timed_wait(system_duration t)
+ {
+ sync::detail::system_duration::native_type time_left = t.get();
+ while (time_left > 0)
+ {
+ const unsigned int dur = time_left > INT_MAX ?
+ static_cast< unsigned int >(INT_MAX) : static_cast< unsigned int >(time_left);
+ const boost::detail::winapi::DWORD_ res = boost::detail::winapi::WaitForSingleObject(m_semaphore, dur);
+ switch (res)
+ {
+ case boost::detail::winapi::wait_object_0:
+ return true;
+
+ case boost::detail::winapi::wait_timeout:
+ time_left -= dur;
+ break;
+
+ default:
+ BOOST_THROW_EXCEPTION(runtime_exception(res, "boost::sync::condition_variable timed_wait failed in WaitForSingleObject"));
+ }
+ }
+ return false;
+ }
+
+ bool woken()
+ {
+ unsigned long const woken_result = boost::detail::winapi::WaitForSingleObject(m_wake_sem, 0);
+ BOOST_ASSERT((woken_result == boost::detail::winapi::timeout) || (woken_result == 0));
+ return woken_result == 0;
+ }
+
+ BOOST_DELETED_FUNCTION(cv_list_entry(cv_list_entry const&))
+ BOOST_DELETED_FUNCTION(cv_list_entry& operator= (cv_list_entry const&))
+};
+
+class basic_condition_variable
+{
+private:
+ typedef boost::sync::mutex mutex_type;
+
+ typedef boost::intrusive_ptr< cv_list_entry > entry_ptr;
+ typedef std::vector< entry_ptr > generation_list;
+
+ template< typename Lockable >
+ class relocker
+ {
+ Lockable& m_lock;
+ bool m_unlocked;
+
+ public:
+ explicit relocker(Lockable& lock) : m_lock(lock), m_unlocked(false)
+ {
+ }
+
+ ~relocker() BOOST_NOEXCEPT_IF(false)
+ {
+ if (m_unlocked)
+ m_lock.lock();
+ }
+
+ void unlock()
+ {
+ m_lock.unlock();
+ m_unlocked = true;
+ }
+
+ BOOST_DELETED_FUNCTION(relocker(relocker const&))
+ BOOST_DELETED_FUNCTION(relocker& operator= (relocker const&))
+ };
+
+ class entry_manager
+ {
+ entry_ptr const m_entry;
+ mutex_type& m_internal_mutex;
+
+ public:
+ entry_manager(entry_ptr const& entry, mutex_type& mutex):
+ m_entry(entry), m_internal_mutex(mutex)
+ {
+ }
+
+ ~entry_manager() BOOST_NOEXCEPT_IF(false)
+ {
+ boost::sync::lock_guard< mutex_type > internal_lock(m_internal_mutex);
+ m_entry->remove_waiter();
+ }
+
+ cv_list_entry* operator->() const BOOST_NOEXCEPT
+ {
+ return m_entry.get();
+ }
+
+ BOOST_DELETED_FUNCTION(entry_manager(entry_manager const&))
+ BOOST_DELETED_FUNCTION(entry_manager& operator= (entry_manager const&))
+ };
+
+private:
+ mutex_type m_internal_mutex;
+ long m_total_count;
+
+ generation_list m_generations;
+ auto_handle m_wake_sem;
+
+public:
+ BOOST_CONSTEXPR basic_condition_variable() : m_total_count(0)
+ {
+ }
+
+ void notify_one() BOOST_NOEXCEPT
+ {
+ if (interlocked_read_acquire(&m_total_count))
+ {
+ boost::sync::lock_guard< mutex_type > internal_lock(m_internal_mutex);
+ if (m_total_count == 0)
+ return;
+
+ wake_waiters(1);
+
+ for(generation_list::iterator it = m_generations.begin(), end = m_generations.end(); it != end; ++it)
+ {
+ (*it)->release(1);
+ }
+ m_generations.erase(std::remove_if(m_generations.begin(), m_generations.end(), &cv_list_entry::no_waiters), m_generations.end());
+ }
+ }
+
+ void notify_all() BOOST_NOEXCEPT
+ {
+ if (interlocked_read_acquire(&m_total_count))
+ {
+ boost::sync::lock_guard< mutex_type > internal_lock(m_internal_mutex);
+ if (m_total_count == 0)
+ return;
+
+ wake_waiters(m_total_count);
+
+ for (generation_list::iterator it = m_generations.begin(), end = m_generations.end(); it != end; ++it)
+ {
+ (*it)->release_waiters();
+ }
+ m_generations.clear();
+ m_wake_sem.reset();
+ }
+ }
+
+ BOOST_DELETED_FUNCTION(basic_condition_variable(basic_condition_variable const&))
+ BOOST_DELETED_FUNCTION(basic_condition_variable& operator= (basic_condition_variable const&))
+
+protected:
+ template< typename Lock >
+ bool do_wait(Lock& lock,timeout abs_time)
+ {
+ relocker< Lock > locker(lock);
+
+ entry_manager entry(get_wait_entry(), m_internal_mutex);
+
+ locker.unlock();
+
+ bool woken = false;
+ do
+ {
+ if (!entry->wait(abs_time))
+ {
+ return false;
+ }
+
+ woken = entry->woken();
+ }
+ while (!woken);
+
+ return woken;
+ }
+
+ template<typename lock_type,typename predicate_type>
+ bool do_wait(lock_type& m, timeout const& abs_time, predicate_type pred)
+ {
+ while (!pred())
+ {
+ if(!do_wait(m, abs_time))
+ return pred();
+ }
+ return true;
+ }
+
+private:
+ void wake_waiters(long count_to_wake)
+ {
+ interlocked_write_release(&m_total_count, m_total_count - count_to_wake);
+ boost::detail::winapi::ReleaseSemaphore(m_wake_sem, count_to_wake, 0);
+ }
+
+ entry_ptr get_wait_entry()
+ {
+ boost::sync::lock_guard< mutex_type > internal_lock(m_internal_mutex);
+
+ if(!m_wake_sem)
+ {
+ m_wake_sem = create_anonymous_semaphore(0, LONG_MAX);
+ BOOST_ASSERT(m_wake_sem);
+ }
+
+ interlocked_write_release(&m_total_count, m_total_count + 1);
+ if (m_generations.empty() || m_generations.back()->is_notified())
+ {
+ entry_ptr new_entry(new cv_list_entry(m_wake_sem));
+ m_generations.push_back(new_entry);
+ return new_entry;
+ }
+ else
+ {
+ m_generations.back()->add_waiter();
+ return m_generations.back();
+ }
+ }
+};
+
+} // namespace windows
+
+} // namespace detail
+
+} // namespace sync
+
+} // namespace boost
+
+#include <boost/sync/detail/footer.hpp>
+
+#endif // BOOST_SYNC_DETAIL_CONDITION_VARIABLES_BASIC_CONDITION_VARIABLE_WINDOWS_HPP_INCLUDED_

Modified: trunk/boost/sync/detail/condition_variables/condition_variable_posix.hpp
==============================================================================
--- trunk/boost/sync/detail/condition_variables/condition_variable_posix.hpp Sun Sep 29 12:14:57 2013 (r86006)
+++ trunk/boost/sync/detail/condition_variables/condition_variable_posix.hpp 2013-09-29 12:42:24 EDT (Sun, 29 Sep 2013) (r86007)
@@ -17,13 +17,14 @@
 #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/mpl/and.hpp>
 #include <boost/sync/detail/config.hpp>
 #include <boost/sync/locks/unique_lock_fwd.hpp>
+#include <boost/sync/exceptions/runtime_exception.hpp>
 #include <boost/sync/exceptions/resource_error.hpp>
 #include <boost/sync/traits/is_condition_variable_compatible.hpp>
 #include <boost/sync/detail/pthread.hpp>
@@ -55,6 +56,10 @@
 public:
 #if defined(PTHREAD_COND_INITIALIZER)
 #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
+#if !defined(BOOST_NO_CXX11_CONSTEXPR)
+#define BOOST_SYNC_DEFINES_CONDITION_VARIABLE_CONSTEXPR_CONSTRUCTOR
+#endif
+
     BOOST_CONSTEXPR condition_variable() BOOST_NOEXCEPT : m_cond(PTHREAD_COND_INITIALIZER)
     {
     }
@@ -70,7 +75,7 @@
     {
         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"));
+ BOOST_THROW_EXCEPTION(resource_error(res, "boost::sync::condition_variable constructor failed in pthread_cond_init"));
     }
 #endif // defined(PTHREAD_COND_INITIALIZER)
 
@@ -106,46 +111,85 @@
     }
 
     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)
+ typename enable_if_c< sync::detail::time_traits< Time >::is_specialized && is_condition_variable_compatible< Mutex >::value, 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));
+ BOOST_ASSERT(lock.owns_lock());
+ return priv_timed_wait(lock, sync::detail::time_traits< Time >::to_sync_unit(t)) == cv_status::no_timeout;
     }
 
     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)
+ typename enable_if< mpl::and_< detail::is_time_tag_of< TimePoint, detail::time_point_tag >, is_condition_variable_compatible< Mutex > >, bool >::type
+ timed_wait(unique_lock< Mutex >& lock, TimePoint const& t, Predicate pred)
     {
+ BOOST_ASSERT(lock.owns_lock());
         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))
+ if (this->priv_timed_wait(lock, abs_timeout) != cv_status::no_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)
+ typename enable_if< mpl::and_< detail::is_time_tag_of< Duration, detail::time_duration_tag >, is_condition_variable_compatible< Mutex > >, bool >::type
+ timed_wait(unique_lock< Mutex >& lock, Duration const& t, Predicate pred)
     {
+ BOOST_ASSERT(lock.owns_lock());
         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))
+ if (this->priv_timed_wait(lock, abs_timeout) != cv_status::no_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)
+ template< typename Mutex, typename TimePoint >
+ typename enable_if< mpl::and_< detail::is_time_tag_of< TimePoint, detail::time_point_tag >, is_condition_variable_compatible< Mutex > >, cv_status >::type
+ wait_until(unique_lock< Mutex >& lock, TimePoint const& abs_time)
+ {
+ BOOST_ASSERT(lock.owns_lock());
+ return priv_timed_wait(lock, sync::detail::time_traits< TimePoint >::to_sync_unit(abs_time));
+ }
+
+ template< typename Mutex, typename TimePoint, typename Predicate >
+ typename enable_if< mpl::and_< detail::is_time_tag_of< TimePoint, detail::time_point_tag >, is_condition_variable_compatible< Mutex > >, bool >::type
+ wait_until(unique_lock< Mutex >& lock, TimePoint const& abs_time, Predicate pred)
     {
- return priv_timed_lock(sync::detail::time_traits< Duration >::to_sync_unit(rel_time));
+ BOOST_ASSERT(lock.owns_lock());
+ 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 (this->priv_timed_wait(lock, abs_timeout) != cv_status::no_timeout)
+ return pred();
+ }
+ return true;
     }
 
- template< typename TimePoint >
- typename detail::enable_if_tag< TimePoint, detail::time_point_tag, bool >::type try_lock_until(TimePoint const& abs_time)
+ template< typename Mutex, typename Duration >
+ typename enable_if< mpl::and_< detail::is_time_tag_of< Duration, detail::time_duration_tag >, is_condition_variable_compatible< Mutex > >, cv_status >::type
+ wait_for(unique_lock< Mutex >& lock, Duration const& rel_time)
     {
- return priv_timed_lock(sync::detail::time_traits< TimePoint >::to_sync_unit(abs_time));
+ BOOST_ASSERT(lock.owns_lock());
+ return priv_timed_wait(lock, sync::detail::time_traits< Duration >::to_sync_unit(rel_time));
+ }
+
+ template< typename Mutex, typename Duration, typename Predicate >
+ typename enable_if< mpl::and_< detail::is_time_tag_of< Duration, detail::time_duration_tag >, is_condition_variable_compatible< Mutex > >, bool >::type
+ wait_for(unique_lock< Mutex >& lock, Duration const& rel_time, Predicate pred)
+ {
+ BOOST_ASSERT(lock.owns_lock());
+ 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 (this->priv_timed_wait(lock, abs_timeout) != cv_status::no_timeout)
+ return pred();
+ }
+ return true;
     }
 
     native_handle_type native_handle() BOOST_NOEXCEPT
@@ -157,57 +201,37 @@
     BOOST_DELETED_FUNCTION(condition_variable& operator= (condition_variable const&))
 
 private:
- bool priv_timed_lock(sync::detail::system_duration dur)
+ template< typename Mutex >
+ cv_status priv_timed_wait(unique_lock< Mutex >& lock, sync::detail::system_duration dur)
     {
- return priv_timed_lock(sync::detail::system_time_point::now() + dur);
+ return priv_timed_wait(lock, sync::detail::system_time_point::now() + dur);
     }
 
- bool priv_timed_lock(sync::detail::system_time_point const& t)
+ template< typename Mutex >
+ cv_status priv_timed_wait(unique_lock< Mutex >& 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)
+ int const res = sync::detail::posix::pthread_cond_timedwait(&m_cond, lock.mutex()->native_handle(), &t.get());
+ if (res == ETIMEDOUT)
+ return cv_status::timeout;
+ else if (res != 0)
+ BOOST_THROW_EXCEPTION(runtime_exception(res, "boost::sync::condition_variable timedwait failed in pthread_cond_timedwait"));
+ return cv_status::no_timeout;
     }
 
- template< typename TimePoint >
- bool priv_timed_lock(sync::detail::chrono_time_point< TimePoint > const& t)
+ template< typename Mutex, typename TimePoint >
+ cv_status priv_timed_wait(unique_lock< Mutex >& 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;
+ if (priv_timed_wait(lock, sync::detail::time_traits< duration >::to_sync_unit(t.get() - now)) == cv_status::no_timeout)
+ return cv_status::no_timeout;
             now = clock::now();
         }
- return false;
+ return cv_status::timeout;
     }
 };
 

Added: trunk/boost/sync/detail/condition_variables/condition_variable_windows.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/sync/detail/condition_variables/condition_variable_windows.hpp 2013-09-29 12:42:24 EDT (Sun, 29 Sep 2013) (r86007)
@@ -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 2007-2008 Anthony Williams
+ * (C) Copyright 2011-2012 Vicente J. Botet Escriba
+ * (C) Copyright 2013 Andrey Semashev
+ */
+/*!
+ * \file detail/condition_variables/condition_variable_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_WINDOWS_HPP_INCLUDED_
+#define BOOST_SYNC_DETAIL_CONDITION_VARIABLES_CONDITION_VARIABLE_WINDOWS_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/assert.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/sync/detail/config.hpp>
+#include <boost/sync/locks/unique_lock_fwd.hpp>
+#include <boost/sync/exceptions/runtime_exception.hpp>
+#include <boost/sync/exceptions/resource_error.hpp>
+#include <boost/sync/traits/is_condition_variable_compatible.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
+
+namespace boost {
+
+namespace sync {
+
+BOOST_SYNC_DETAIL_OPEN_ABI_NAMESPACE {
+
+class condition_variable
+{
+private:
+ pthread_cond_t m_cond;
+
+public:
+#if defined(PTHREAD_COND_INITIALIZER)
+#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
+#if !defined(BOOST_NO_CXX11_CONSTEXPR)
+#define BOOST_SYNC_DEFINES_CONDITION_VARIABLE_CONSTEXPR_CONSTRUCTOR
+#endif
+
+ 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::sync::condition_variable 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 && is_condition_variable_compatible< Mutex >::value, bool >::type
+ timed_wait(unique_lock< Mutex >& lock, Time const& t)
+ {
+ BOOST_ASSERT(lock.owns_lock());
+ return priv_timed_wait(lock, sync::detail::time_traits< Time >::to_sync_unit(t)) == cv_status::no_timeout;
+ }
+
+ template< typename Mutex, typename TimePoint, typename Predicate >
+ typename enable_if< mpl::and_< detail::is_time_tag_of< TimePoint, detail::time_point_tag >, is_condition_variable_compatible< Mutex > >, bool >::type
+ timed_wait(unique_lock< Mutex >& lock, TimePoint const& t, Predicate pred)
+ {
+ BOOST_ASSERT(lock.owns_lock());
+ 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) != cv_status::no_timeout)
+ return pred();
+ }
+ return true;
+ }
+
+ template< typename Mutex, typename Duration, typename Predicate >
+ typename enable_if< mpl::and_< detail::is_time_tag_of< Duration, detail::time_duration_tag >, is_condition_variable_compatible< Mutex > >, bool >::type
+ timed_wait(unique_lock< Mutex >& lock, Duration const& t, Predicate pred)
+ {
+ BOOST_ASSERT(lock.owns_lock());
+ 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) != cv_status::no_timeout)
+ return pred();
+ }
+ return true;
+ }
+
+ template< typename Mutex, typename TimePoint >
+ typename enable_if< mpl::and_< detail::is_time_tag_of< TimePoint, detail::time_point_tag >, is_condition_variable_compatible< Mutex > >, cv_status >::type
+ wait_until(unique_lock< Mutex >& lock, TimePoint const& abs_time)
+ {
+ BOOST_ASSERT(lock.owns_lock());
+ return priv_timed_wait(lock, sync::detail::time_traits< TimePoint >::to_sync_unit(abs_time));
+ }
+
+ template< typename Mutex, typename TimePoint, typename Predicate >
+ typename enable_if< mpl::and_< detail::is_time_tag_of< TimePoint, detail::time_point_tag >, is_condition_variable_compatible< Mutex > >, bool >::type
+ wait_until(unique_lock< Mutex >& lock, TimePoint const& abs_time, Predicate pred)
+ {
+ BOOST_ASSERT(lock.owns_lock());
+ 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 (this->priv_timed_wait(lock, abs_timeout) != cv_status::no_timeout)
+ return pred();
+ }
+ return true;
+ }
+
+ template< typename Mutex, typename Duration >
+ typename enable_if< mpl::and_< detail::is_time_tag_of< Duration, detail::time_duration_tag >, is_condition_variable_compatible< Mutex > >, cv_status >::type
+ wait_for(unique_lock< Mutex >& lock, Duration const& rel_time)
+ {
+ BOOST_ASSERT(lock.owns_lock());
+ return priv_timed_wait(lock, sync::detail::time_traits< Duration >::to_sync_unit(rel_time));
+ }
+
+ template< typename Mutex, typename Duration, typename Predicate >
+ typename enable_if< mpl::and_< detail::is_time_tag_of< Duration, detail::time_duration_tag >, is_condition_variable_compatible< Mutex > >, bool >::type
+ wait_for(unique_lock< Mutex >& lock, Duration const& rel_time, Predicate pred)
+ {
+ BOOST_ASSERT(lock.owns_lock());
+ 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 (this->priv_timed_wait(lock, abs_timeout) != cv_status::no_timeout)
+ return pred();
+ }
+ return true;
+ }
+
+ 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:
+ template< typename Mutex >
+ cv_status priv_timed_wait(unique_lock< Mutex >& lock, sync::detail::system_duration dur)
+ {
+ return priv_timed_wait(lock, sync::detail::system_time_point::now() + dur);
+ }
+
+ template< typename Mutex >
+ cv_status priv_timed_wait(unique_lock< Mutex >& lock, sync::detail::system_time_point const& t)
+ {
+ int const res = sync::detail::posix::pthread_cond_timedwait(&m_cond, lock.mutex()->native_handle(), &t.get());
+ if (res == ETIMEDOUT)
+ return cv_status::timeout;
+ else if (res != 0)
+ BOOST_THROW_EXCEPTION(runtime_exception(res, "boost::sync::condition_variable timedwait failed in pthread_cond_timedwait"));
+ return cv_status::no_timeout;
+ }
+
+ template< typename Mutex, typename TimePoint >
+ cv_status priv_timed_wait(unique_lock< Mutex >& lock, sync::detail::chrono_time_point< TimePoint > const& t)
+ {
+ 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_wait(lock, sync::detail::time_traits< duration >::to_sync_unit(t.get() - now)) == cv_status::no_timeout)
+ return cv_status::no_timeout;
+ now = clock::now();
+ }
+ return cv_status::timeout;
+ }
+};
+
+} // namespace posix
+
+} // namespace sync
+
+} // namespace boost
+
+#include <boost/sync/detail/footer.hpp>
+
+#endif // BOOST_SYNC_DETAIL_CONDITION_VARIABLES_CONDITION_VARIABLE_WINDOWS_HPP_INCLUDED_

Modified: trunk/boost/sync/detail/mutexes/mutex_posix.hpp
==============================================================================
--- trunk/boost/sync/detail/mutexes/mutex_posix.hpp Sun Sep 29 12:14:57 2013 (r86006)
+++ trunk/boost/sync/detail/mutexes/mutex_posix.hpp 2013-09-29 12:42:24 EDT (Sun, 29 Sep 2013) (r86007)
@@ -52,6 +52,10 @@
 public:
 #if defined(PTHREAD_MUTEX_INITIALIZER)
 #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
+#if !defined(BOOST_NO_CXX11_CONSTEXPR)
+#define BOOST_SYNC_DEFINES_MUTEX_CONSTEXPR_CONSTRUCTOR
+#endif
+
     BOOST_CONSTEXPR mutex() BOOST_NOEXCEPT : m_mutex(PTHREAD_MUTEX_INITIALIZER)
     {
     }

Modified: trunk/boost/sync/detail/mutexes/mutex_windows.hpp
==============================================================================
--- trunk/boost/sync/detail/mutexes/mutex_windows.hpp Sun Sep 29 12:14:57 2013 (r86006)
+++ trunk/boost/sync/detail/mutexes/mutex_windows.hpp 2013-09-29 12:42:24 EDT (Sun, 29 Sep 2013) (r86007)
@@ -62,6 +62,10 @@
     boost::detail::winapi::HANDLE_ m_event;
 
 public:
+#if !defined(BOOST_NO_CXX11_CONSTEXPR)
+#define BOOST_SYNC_DEFINES_MUTEX_CONSTEXPR_CONSTRUCTOR
+#endif
+
     BOOST_CONSTEXPR mutex() BOOST_NOEXCEPT : m_event(NULL), m_active_count(0)
     {
     }

Modified: trunk/boost/sync/detail/mutexes/timed_mutex_posix.hpp
==============================================================================
--- trunk/boost/sync/detail/mutexes/timed_mutex_posix.hpp Sun Sep 29 12:14:57 2013 (r86006)
+++ trunk/boost/sync/detail/mutexes/timed_mutex_posix.hpp 2013-09-29 12:42:24 EDT (Sun, 29 Sep 2013) (r86007)
@@ -17,7 +17,6 @@
 #ifndef BOOST_SYNC_DETAIL_MUTEXES_TIMED_MUTEX_POSIX_HPP_INCLUDED_
 #define BOOST_SYNC_DETAIL_MUTEXES_TIMED_MUTEX_POSIX_HPP_INCLUDED_
 
-#include <time.h>
 #include <cstddef>
 #include <boost/assert.hpp>
 #include <boost/throw_exception.hpp>
@@ -62,6 +61,10 @@
 public:
 #if defined(PTHREAD_MUTEX_INITIALIZER) && (defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK) || defined(PTHREAD_COND_INITIALIZER))
 #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
+#if !defined(BOOST_NO_CXX11_CONSTEXPR)
+#define BOOST_SYNC_DEFINES_TIMED_MUTEX_CONSTEXPR_CONSTRUCTOR
+#endif
+
     BOOST_CONSTEXPR timed_mutex() BOOST_NOEXCEPT :
         m_mutex(PTHREAD_MUTEX_INITIALIZER)
 #if !defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK)

Modified: trunk/boost/sync/detail/mutexes/timed_mutex_windows.hpp
==============================================================================
--- trunk/boost/sync/detail/mutexes/timed_mutex_windows.hpp Sun Sep 29 12:14:57 2013 (r86006)
+++ trunk/boost/sync/detail/mutexes/timed_mutex_windows.hpp 2013-09-29 12:42:24 EDT (Sun, 29 Sep 2013) (r86007)
@@ -52,6 +52,10 @@
     mutex m_mutex;
 
 public:
+#if !defined(BOOST_NO_CXX11_CONSTEXPR)
+#define BOOST_SYNC_DEFINES_TIMED_MUTEX_CONSTEXPR_CONSTRUCTOR
+#endif
+
     BOOST_CONSTEXPR timed_mutex() BOOST_NOEXCEPT : m_mutex()
     {
     }

Modified: trunk/boost/sync/detail/time_traits.hpp
==============================================================================
--- trunk/boost/sync/detail/time_traits.hpp Sun Sep 29 12:14:57 2013 (r86006)
+++ trunk/boost/sync/detail/time_traits.hpp 2013-09-29 12:42:24 EDT (Sun, 29 Sep 2013) (r86007)
@@ -16,6 +16,7 @@
 #ifndef BOOST_SYNC_DETAIL_TIME_TRAITS_HPP_INCLUDED_
 #define BOOST_SYNC_DETAIL_TIME_TRAITS_HPP_INCLUDED_
 
+#include <boost/mpl/bool.hpp>
 #include <boost/sync/detail/config.hpp>
 #include <boost/sync/detail/header.hpp>
 
@@ -49,6 +50,12 @@
     typedef R type;
 };
 
+template< typename T, typename TagT >
+struct is_time_tag_of : mpl::false_ {};
+
+template< typename T >
+struct is_time_tag_of< T, typename time_traits< T >::tag > : mpl::true_ {};
+
 } // namespace detail
 
 } // namespace sync

Added: trunk/boost/sync/detail/windows_primitives.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/sync/detail/windows_primitives.hpp 2013-09-29 12:42:24 EDT (Sun, 29 Sep 2013) (r86007)
@@ -0,0 +1,65 @@
+/*
+ * 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 2005-2007 Anthony Williams
+ * (C) Copyright 2007 David Deakins
+ * (C) Copyright 2013 Andrey Semashev
+ */
+/*!
+ * \file windows_primitives.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_WINDOWS_PRIMITIVES_HPP_INCLUDED_
+#define BOOST_SYNC_DETAIL_WINDOWS_PRIMITIVES_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/detail/winapi/synchronization.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 {
+
+namespace detail {
+
+namespace windows {
+
+BOOST_FORCEINLINE boost::detail::winapi::HANDLE_ create_anonymous_event(bool manual_reset, bool initial_state)
+{
+#if !defined(BOOST_NO_ANSI_APIS)
+ return boost::detail::winapi::CreateEventA(NULL, manual_reset, initial_state, NULL);
+#else
+ return boost::detail::winapi::CreateEventW(NULL, manual_reset, initial_state, NULL);
+#endif
+}
+
+BOOST_FORCEINLINE boost::detail::winapi::HANDLE_ create_anonymous_semaphore(long initial_count, long max_count)
+{
+#if !defined(BOOST_NO_ANSI_APIS)
+ return CreateSemaphoreA(NULL, initial_count, max_count, NULL);
+#else
+ return CreateSemaphoreW(NULL, initial_count, max_count, NULL);
+#endif
+}
+
+} // namespace windows
+
+} // namespace detail
+
+} // namespace sync
+
+} // namespace boost
+
+#include <boost/sync/detail/footer.hpp>
+
+#endif // BOOST_SYNC_DETAIL_WINDOWS_PRIMITIVES_HPP_INCLUDED_

Modified: trunk/boost/sync/locks.hpp
==============================================================================
--- trunk/boost/sync/locks.hpp Sun Sep 29 12:14:57 2013 (r86006)
+++ trunk/boost/sync/locks.hpp 2013-09-29 12:42:24 EDT (Sun, 29 Sep 2013) (r86007)
@@ -21,6 +21,7 @@
 #endif
 
 #include <boost/sync/locks/lock_guard.hpp>
+#include <boost/sync/locks/unlock_guard.hpp>
 #include <boost/sync/locks/shared_lock_guard.hpp>
 #include <boost/sync/locks/unique_lock.hpp>
 #include <boost/sync/locks/shared_lock.hpp>

Added: trunk/boost/sync/locks/unlock_guard.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/sync/locks/unlock_guard.hpp 2013-09-29 12:42:24 EDT (Sun, 29 Sep 2013) (r86007)
@@ -0,0 +1,65 @@
+/*
+ * 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 locks/unlock_guard.hpp
+ *
+ * \brief This header defines a scope guard temporarily releases a lock.
+ */
+
+#ifndef BOOST_SYNC_LOCKS_UNLOCK_GUARD_HPP_INCLUDED_
+#define BOOST_SYNC_LOCKS_UNLOCK_GUARD_HPP_INCLUDED_
+
+#include <boost/sync/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#include <boost/sync/locks/unlock_guard_fwd.hpp>
+
+#include <boost/sync/detail/header.hpp>
+
+namespace boost {
+
+namespace sync {
+
+/*!
+ * \brief A scope guard that releases a lock
+ */
+template< typename Lockable >
+class unlock_guard
+{
+public:
+ // Note: naming is for compatibility with other lock types
+ typedef Lockable mutex_type;
+
+private:
+ mutex_type& m_lockable;
+
+public:
+ explicit unlock_guard(mutex_type& m) BOOST_NOEXCEPT : m_lockable(m)
+ {
+ m.unlock();
+ }
+
+ ~unlock_guard() BOOST_NOEXCEPT_IF(false)
+ {
+ m_lockable.lock();
+ }
+
+ BOOST_DELETED_FUNCTION(unlock_guard(unlock_guard const&))
+ BOOST_DELETED_FUNCTION(unlock_guard& operator= (unlock_guard const&))
+};
+
+} // namespace sync
+
+} // namespace boost
+
+#include <boost/sync/detail/footer.hpp>
+
+#endif // BOOST_SYNC_LOCKS_UNLOCK_GUARD_HPP_INCLUDED_

Added: trunk/boost/sync/locks/unlock_guard_fwd.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/sync/locks/unlock_guard_fwd.hpp 2013-09-29 12:42:24 EDT (Sun, 29 Sep 2013) (r86007)
@@ -0,0 +1,41 @@
+/*
+ * 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 locks/unlock_guard_fwd.hpp
+ *
+ * \brief This header declares a scope guard that temporarily releases the lock.
+ */
+
+#ifndef BOOST_SYNC_LOCKS_UNLOCK_GUARD_FWD_HPP_INCLUDED_
+#define BOOST_SYNC_LOCKS_UNLOCK_GUARD_FWD_HPP_INCLUDED_
+
+#include <boost/sync/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#include <boost/sync/detail/header.hpp>
+
+namespace boost {
+
+namespace sync {
+
+/*!
+ * \brief An unlock scope guard
+ */
+template< typename Lockable >
+class unlock_guard;
+
+} // namespace sync
+
+} // namespace boost
+
+#include <boost/sync/detail/footer.hpp>
+
+#endif // BOOST_SYNC_LOCKS_UNLOCK_GUARD_FWD_HPP_INCLUDED_


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