$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: anthony_at_[hidden]
Date: 2007-10-19 13:40:05
Author: anthonyw
Date: 2007-10-19 13:40:04 EDT (Fri, 19 Oct 2007)
New Revision: 40191
URL: http://svn.boost.org/trac/boost/changeset/40191
Log:
New condition_variable and condition_variable_any as per proposed C++0x interface
Added:
   trunk/boost/thread/condition_variable.hpp   (contents, props changed)
   trunk/boost/thread/pthread/condition_variable.hpp   (contents, props changed)
   trunk/boost/thread/win32/condition_variable.hpp   (contents, props changed)
Removed:
   trunk/libs/thread/src/barrier.cpp
   trunk/libs/thread/src/condition.cpp
Text files modified: 
   trunk/boost/thread/barrier.hpp                |    65 ++++++++-----                           
   trunk/boost/thread/condition.hpp              |   198 +-------------------------------------- 
   trunk/boost/thread/exceptions.hpp             |    12 ++                                      
   trunk/boost/thread/pthread/mutex.hpp          |     7 +                                       
   trunk/boost/thread/pthread/shared_mutex.hpp   |     7                                         
   trunk/boost/thread/thread.hpp                 |     1                                         
   trunk/boost/thread/win32/interlocked_read.hpp |    19 +++                                     
   trunk/boost/thread/xtime.hpp                  |    13 ++                                      
   trunk/libs/thread/build/Jamfile.v2            |     4                                         
   9 files changed, 102 insertions(+), 224 deletions(-)
Modified: trunk/boost/thread/barrier.hpp
==============================================================================
--- trunk/boost/thread/barrier.hpp	(original)
+++ trunk/boost/thread/barrier.hpp	2007-10-19 13:40:04 EDT (Fri, 19 Oct 2007)
@@ -1,5 +1,6 @@
 // Copyright (C) 2002-2003
 // David Moore, William E. Kempf
+// Copyright (C) 2007 Anthony Williams
 //
 //  Distributed under the Boost Software License, Version 1.0. (See accompanying 
 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -11,33 +12,47 @@
 
 #include <boost/thread/mutex.hpp>
 #include <boost/thread/condition.hpp>
+#include <string>
+#include <stdexcept>
 
-namespace boost {
-
-class BOOST_THREAD_DECL barrier
+namespace boost
 {
-public:
-    barrier(unsigned int count);
-    ~barrier();
-
-    bool wait();
-
-private:
-    mutex m_mutex;
-// disable warnings about non dll import
-// see: http://www.boost.org/more/separate_compilation.html#dlls
-#ifdef BOOST_MSVC
-#   pragma warning(push)
-#   pragma warning(disable: 4251 4231 4660 4275)
-#endif
-    condition m_cond;
-#ifdef BOOST_MSVC
-#   pragma warning(pop)
-#endif
-    unsigned int m_threshold;
-    unsigned int m_count;
-    unsigned int m_generation;
-};
+
+    class barrier
+    {
+    public:
+        barrier(unsigned int count)
+            : m_threshold(count), m_count(count), m_generation(0)
+        {
+            if (count == 0)
+                throw std::invalid_argument("count cannot be zero.");
+        }
+    
+        bool wait()
+        {
+            boost::mutex::scoped_lock lock(m_mutex);
+            unsigned int gen = m_generation;
+        
+            if (--m_count == 0)
+            {
+                m_generation++;
+                m_count = m_threshold;
+                m_cond.notify_all();
+                return true;
+            }
+
+            while (gen == m_generation)
+                m_cond.wait(lock);
+            return false;
+        }
+
+    private:
+        mutex m_mutex;
+        condition m_cond;
+        unsigned int m_threshold;
+        unsigned int m_count;
+        unsigned int m_generation;
+    };
 
 }   // namespace boost
 
Modified: trunk/boost/thread/condition.hpp
==============================================================================
--- trunk/boost/thread/condition.hpp	(original)
+++ trunk/boost/thread/condition.hpp	2007-10-19 13:40:04 EDT (Fri, 19 Oct 2007)
@@ -1,196 +1,10 @@
-// Copyright (C) 2001-2003
-// William E. Kempf
-// Copyright (C) 2007 Anthony Williams
-//
-//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
-//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_THREAD_CONDITION_HPP
+#define BOOST_THREAD_CONDITION_HPP
+#include <boost/thread/condition_variable.hpp>
 
-#ifndef BOOST_CONDITION_WEK070601_HPP
-#define BOOST_CONDITION_WEK070601_HPP
-
-#include <boost/thread/detail/config.hpp>
-
-#include <boost/thread/exceptions.hpp>
-#include <boost/utility.hpp>
-
-#if defined(BOOST_HAS_PTHREADS)
-#   include <pthread.h>
-#elif defined(BOOST_HAS_MPTASKS)
-#   include "scoped_critical_region.hpp"
-#endif
-
-namespace boost {
-
-struct xtime;
-// disable warnings about non dll import
-// see: http://www.boost.org/more/separate_compilation.html#dlls
-#ifdef BOOST_MSVC
-#   pragma warning(push)
-#   pragma warning(disable: 4251 4231 4660 4275)
-#endif
-
-namespace detail {
-
-class BOOST_THREAD_DECL condition_impl : private noncopyable
+namespace boost
 {
-    friend class condition;
-
-public:
-    condition_impl();
-    ~condition_impl();
-
-    void notify_one();
-    void notify_all();
-
-#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
-    void enter_wait();
-    void do_wait();
-    bool do_timed_wait(const xtime& xt);
-#elif defined(BOOST_HAS_PTHREADS)
-    void do_wait(pthread_mutex_t* pmutex);
-    bool do_timed_wait(const xtime& xt, pthread_mutex_t* pmutex);
-#endif
-
-#if defined(BOOST_HAS_WINTHREADS)
-    void* m_gate;
-    void* m_queue;
-    void* m_mutex;
-    unsigned m_gone;  // # threads that timed out and never made it to m_queue
-    unsigned long m_blocked; // # threads blocked on the condition
-    unsigned m_waiting; // # threads no longer waiting for the condition but
-                        // still waiting to be removed from m_queue
-#elif defined(BOOST_HAS_PTHREADS)
-    pthread_cond_t m_condition;
-    pthread_mutex_t m_mutex;
-#elif defined(BOOST_HAS_MPTASKS)
-    MPSemaphoreID m_gate;
-    MPSemaphoreID m_queue;
-    threads::mac::detail::scoped_critical_region m_mutex;
-    threads::mac::detail::scoped_critical_region m_mutex_mutex;
-    unsigned m_gone; // # threads that timed out and never made it to m_queue
-    unsigned long m_blocked; // # threads blocked on the condition
-    unsigned m_waiting; // # threads no longer waiting for the condition but
-                        // still waiting to be removed from m_queue
-#endif
-};
-
-} // namespace detail
-
-class condition : private noncopyable
-{
-public:
-    condition() { }
-    ~condition() { }
-
-    void notify_one() { m_impl.notify_one(); }
-    void notify_all() { m_impl.notify_all(); }
-
-    template <typename L>
-    void wait(L& lock)
-    {
-        if (!lock)
-            throw lock_error();
-
-        do_wait(*lock.mutex());
-    }
-
-    template <typename L, typename Pr>
-    void wait(L& lock, Pr pred)
-    {
-        if (!lock)
-            throw lock_error();
-
-        while (!pred())
-            do_wait(*lock.mutex());
-    }
+    typedef condition_variable_any condition;
+}
 
-    template <typename L>
-    bool timed_wait(L& lock, const xtime& xt)
-    {
-        if (!lock)
-            throw lock_error();
-
-        return do_timed_wait(*lock.mutex(), xt);
-    }
-
-    template <typename L, typename Pr>
-    bool timed_wait(L& lock, const xtime& xt, Pr pred)
-    {
-        if (!lock)
-            throw lock_error();
-
-        while (!pred())
-        {
-            if (!do_timed_wait(*lock.mutex(), xt))
-                return false;
-        }
-
-        return true;
-    }
-
-private:
-    detail::condition_impl m_impl;
-
-    template <typename M>
-    void do_wait(M& mutex)
-    {
-#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
-        m_impl.enter_wait();
-#else
-        pthread_mutex_lock(&m_impl.m_mutex);
 #endif
-
-        mutex.unlock();
-
-#if defined(BOOST_HAS_PTHREADS)
-        m_impl.do_wait(&m_impl.m_mutex);
-#elif (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
-        m_impl.do_wait();
-#endif
-
-#if defined(BOOST_HAS_PTHREADS)
-        pthread_mutex_unlock(&m_impl.m_mutex);
-#endif
-        mutex.lock();
-    }
-
-    template <typename M>
-    bool do_timed_wait(M& mutex, const xtime& xt)
-    {
-#if (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
-        m_impl.enter_wait();
-#else
-        pthread_mutex_lock(&m_impl.m_mutex);
-#endif
-
-        mutex.unlock();
-
-        bool ret = false;
-
-#if defined(BOOST_HAS_PTHREADS)
-        ret = m_impl.do_timed_wait(xt, &m_impl.m_mutex);
-#elif (defined(BOOST_HAS_WINTHREADS) || defined(BOOST_HAS_MPTASKS))
-        ret = m_impl.do_timed_wait(xt);
-#endif
-
-#if defined(BOOST_HAS_PTHREADS)
-        pthread_mutex_unlock(&m_impl.m_mutex);
-#endif
-        mutex.lock();
-
-        return ret;
-    }
-};
-#ifdef BOOST_MSVC
-#   pragma warning(pop)
-#endif
-} // namespace boost
-
-// Change Log:
-//    8 Feb 01  WEKEMPF Initial version.
-//   22 May 01  WEKEMPF Modified to use xtime for time outs.
-//   23 May 01  WEKEMPF Removed "duration" timed_waits, as they are too
-//                      difficult to use with spurious wakeups.
-//    3 Jan 03  WEKEMPF Modified for DLL implementation.
-
-#endif // BOOST_CONDITION_WEK070601_HPP
Added: trunk/boost/thread/condition_variable.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/condition_variable.hpp	2007-10-19 13:40:04 EDT (Fri, 19 Oct 2007)
@@ -0,0 +1,15 @@
+#ifndef BOOST_THREAD_CONDITION_VARIABLE_HPP
+#define BOOST_THREAD_CONDITION_VARIABLE_HPP
+
+//  condition_variable.hpp
+//
+//  (C) Copyright 2007 Anthony Williams 
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/thread/detail/platform.hpp>
+#include BOOST_THREAD_PLATFORM(condition_variable.hpp)
+
+#endif
Modified: trunk/boost/thread/exceptions.hpp
==============================================================================
--- trunk/boost/thread/exceptions.hpp	(original)
+++ trunk/boost/thread/exceptions.hpp	2007-10-19 13:40:04 EDT (Fri, 19 Oct 2007)
@@ -1,5 +1,6 @@
 // Copyright (C) 2001-2003
 // William E. Kempf
+// Copyright (C) 2007 Anthony Williams
 //
 //  Distributed under the Boost Software License, Version 1.0. (See accompanying 
 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -35,6 +36,17 @@
     int m_sys_err;
 };
 
+    class condition_error:
+        public std::exception
+    {
+    public:
+        const char* what() const throw()
+        {
+            return "Condition error";
+        }
+    };
+    
+
 class BOOST_THREAD_DECL lock_error : public thread_exception
 {
 public:
Added: trunk/boost/thread/pthread/condition_variable.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/pthread/condition_variable.hpp	2007-10-19 13:40:04 EDT (Fri, 19 Oct 2007)
@@ -0,0 +1,194 @@
+#ifndef BOOST_THREAD_CONDITION_VARIABLE_WIN32_HPP
+#define BOOST_THREAD_CONDITION_VARIABLE_WIN32_HPP
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// (C) Copyright 2007 Anthony Williams
+
+#include <boost/thread/mutex.hpp>
+#include <limits.h>
+#include <boost/assert.hpp>
+#include <algorithm>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <pthread.h>
+#include "timespec.hpp"
+#include "pthread_mutex_scoped_lock.hpp"
+
+namespace boost
+{
+    class condition_variable
+    {
+    private:
+        pthread_cond_t cond;
+        
+        condition_variable(condition_variable&);
+        condition_variable& operator=(condition_variable&);
+    public:
+        condition_variable()
+        {
+            int const res=pthread_cond_init(&cond,NULL);
+            if(res)
+            {
+                throw thread_resource_error();
+            }
+        }
+        ~condition_variable()
+        {
+            int const res=pthread_cond_destroy(&cond);
+            BOOST_ASSERT(!res);
+        }
+
+        void wait(unique_lock<mutex>& m)
+        {
+            int const cond_res=pthread_cond_wait(&cond,m.mutex()->native_handle());
+            BOOST_ASSERT(!cond_res);
+        }
+
+        template<typename predicate_type>
+        void wait(unique_lock<mutex>& m,predicate_type pred)
+        {
+            while(!pred()) wait(m);
+        }
+
+        bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until)
+        {
+            struct timespec const timeout=detail::get_timespec(wait_until);
+            int const cond_res=pthread_cond_timedwait(&cond,m.mutex()->native_handle(),&timeout);
+            if(cond_res==ETIMEDOUT)
+            {
+                return false;
+            }
+            BOOST_ASSERT(!cond_res);
+            return true;
+        }
+
+        template<typename predicate_type>
+        bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until,predicate_type pred)
+        {
+            while (!pred())
+            {
+                if(!timed_wait(m, wait_until))
+                    return false;
+            }
+            return true;
+        }
+
+        void notify_one()
+        {
+            int const res=pthread_cond_signal(&cond);
+            BOOST_ASSERT(!res);
+        }
+        
+        void notify_all()
+        {
+            int const res=pthread_cond_broadcast(&cond);
+            BOOST_ASSERT(!res);
+        }
+    };
+    
+    class condition_variable_any
+    {
+        pthread_mutex_t internal_mutex;
+        pthread_cond_t cond;
+
+        condition_variable_any(condition_variable&);
+        condition_variable_any& operator=(condition_variable&);
+
+    public:
+        condition_variable_any()
+        {
+            int const res=pthread_mutex_init(&internal_mutex,NULL);
+            if(res)
+            {
+                throw thread_resource_error();
+            }
+            int const res2=pthread_cond_init(&cond,NULL);
+            if(res2)
+            {
+                int const destroy_res=pthread_mutex_destroy(&internal_mutex);
+                BOOST_ASSERT(!destroy_res);
+                throw thread_resource_error();
+            }
+        }
+        ~condition_variable_any()
+        {
+            int const res=pthread_mutex_destroy(&internal_mutex);
+            BOOST_ASSERT(!res);
+            int const res2=pthread_cond_destroy(&cond);
+            BOOST_ASSERT(!res2);
+        }
+        
+        template<typename lock_type>
+        void wait(lock_type& m)
+        {
+            int res=0;
+            {
+                boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
+                m.unlock();
+                res=pthread_cond_wait(&cond,&internal_mutex);
+            }
+            m.lock();
+            if(res)
+            {
+                throw condition_error();
+            }
+        }
+
+        template<typename lock_type,typename predicate_type>
+        void wait(lock_type& m,predicate_type pred)
+        {
+            while(!pred()) wait(m);
+        }
+        
+        template<typename lock_type>
+        bool timed_wait(lock_type& m,boost::system_time const& wait_until)
+        {
+            struct timespec const timeout=detail::get_timespec(wait_until);
+            int res=0;
+            {
+                boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
+                m.unlock();
+                res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
+            }
+            m.lock();
+            if(res==ETIMEDOUT)
+            {
+                return false;
+            }
+            if(res)
+            {
+                throw condition_error();
+            }
+            return true;
+        }
+
+        template<typename lock_type,typename predicate_type>
+        bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred)
+        {
+            while (!pred())
+            {
+                if(!timed_wait(m, wait_until))
+                    return false;
+            }
+            return true;
+        }
+
+        void notify_one()
+        {
+            boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
+            int const res=pthread_cond_signal(&cond);
+            BOOST_ASSERT(!res);
+        }
+        
+        void notify_all()
+        {
+            boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
+            int const res=pthread_cond_broadcast(&cond);
+            BOOST_ASSERT(!res);
+        }
+    };
+
+}
+
+#endif
Modified: trunk/boost/thread/pthread/mutex.hpp
==============================================================================
--- trunk/boost/thread/pthread/mutex.hpp	(original)
+++ trunk/boost/thread/pthread/mutex.hpp	2007-10-19 13:40:04 EDT (Fri, 19 Oct 2007)
@@ -62,6 +62,13 @@
             BOOST_ASSERT(!res || res==EBUSY);
             return !res;
         }
+
+        typedef pthread_mutex_t* native_handle_type;
+        native_handle_type native_handle() const
+        {
+            return &m;
+        }
+
         typedef unique_lock<mutex> scoped_lock;
         typedef scoped_lock scoped_try_lock;
     };
Modified: trunk/boost/thread/pthread/shared_mutex.hpp
==============================================================================
--- trunk/boost/thread/pthread/shared_mutex.hpp	(original)
+++ trunk/boost/thread/pthread/shared_mutex.hpp	2007-10-19 13:40:04 EDT (Fri, 19 Oct 2007)
@@ -11,7 +11,6 @@
 #include <boost/static_assert.hpp>
 #include <boost/thread/mutex.hpp>
 #include <boost/thread/condition.hpp>
-#include <boost/thread/xtime.hpp>
 
 namespace boost
 {
@@ -95,7 +94,7 @@
                     return true;
                 }
                 
-                if(!shared_cond.timed_wait(lock,get_xtime(timeout)))
+                if(!shared_cond.timed_wait(lock,timeout))
                 {
                     return false;
                 }
@@ -157,7 +156,7 @@
                     state.exclusive=true;
                     return true;
                 }
-                if(!exclusive_cond.timed_wait(lock,get_xtime(timeout)))
+                if(!exclusive_cond.timed_wait(lock,timeout))
                 {
                     return false;
                 }
@@ -216,7 +215,7 @@
                     return true;
                 }
                 
-                if(!shared_cond.timed_wait(lock,get_xtime(timeout)))
+                if(!shared_cond.timed_wait(lock,timeout))
                 {
                     return false;
                 }
Modified: trunk/boost/thread/thread.hpp
==============================================================================
--- trunk/boost/thread/thread.hpp	(original)
+++ trunk/boost/thread/thread.hpp	2007-10-19 13:40:04 EDT (Fri, 19 Oct 2007)
@@ -17,7 +17,6 @@
 
 #if defined(BOOST_HAS_PTHREADS)
 #   include <pthread.h>
-#   include <boost/thread/condition.hpp>
 #elif defined(BOOST_HAS_MPTASKS)
 #   include <Multiprocessing.h>
 #endif
Added: trunk/boost/thread/win32/condition_variable.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/win32/condition_variable.hpp	2007-10-19 13:40:04 EDT (Fri, 19 Oct 2007)
@@ -0,0 +1,309 @@
+#ifndef BOOST_THREAD_CONDITION_VARIABLE_WIN32_HPP
+#define BOOST_THREAD_CONDITION_VARIABLE_WIN32_HPP
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// (C) Copyright 2007 Anthony Williams
+
+#include <boost/thread/mutex.hpp>
+#include "thread_primitives.hpp"
+#include <limits.h>
+#include <boost/assert.hpp>
+#include <algorithm>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/thread_time.hpp>
+#include "interlocked_read.hpp"
+
+namespace boost
+{
+    namespace detail
+    {
+        class basic_condition_variable
+        {
+            boost::mutex internal_mutex;
+            long total_count;
+            unsigned active_generation_count;
+
+            struct list_entry
+            {
+                detail::win32::handle semaphore;
+                long count;
+                bool notified;
+            };
+
+            BOOST_STATIC_CONSTANT(unsigned,generation_count=3);
+
+            list_entry generations[generation_count];
+            detail::win32::handle wake_sem;
+
+            static bool no_waiters(list_entry const& entry)
+            {
+                return entry.count==0;
+            }
+
+            void shift_generations_down()
+            {
+                list_entry* const last_active_entry=std::remove_if(generations,generations+generation_count,no_waiters);
+                if(last_active_entry==generations+generation_count)
+                {
+                    broadcast_entry(generations[generation_count-1],false);
+                }
+                else
+                {
+                    active_generation_count=(last_active_entry-generations)+1;
+                }
+            
+                std::copy_backward(generations,generations+active_generation_count-1,generations+active_generation_count);
+                generations[0]=list_entry();
+            }
+
+            void broadcast_entry(list_entry& entry,bool wake)
+            {
+                long const count_to_wake=entry.count;
+                detail::interlocked_write_release(&total_count,total_count-count_to_wake);
+                if(wake)
+                {
+                    detail::win32::ReleaseSemaphore(wake_sem,count_to_wake,0);
+                }
+                detail::win32::ReleaseSemaphore(entry.semaphore,count_to_wake,0);
+                entry.count=0;
+                dispose_entry(entry);
+            }
+        
+
+            void dispose_entry(list_entry& entry)
+            {
+                if(entry.semaphore)
+                {
+                    unsigned long const close_result=detail::win32::CloseHandle(entry.semaphore);
+                    BOOST_ASSERT(close_result);
+                    entry.semaphore=0;
+                }
+                entry.notified=false;
+            }
+
+            template<typename lock_type>
+            struct relocker
+            {
+                lock_type& lock;
+                bool unlocked;
+                
+                relocker(lock_type& lock_):
+                    lock(lock_),unlocked(false)
+                {}
+                void unlock()
+                {
+                    lock.unlock();
+                    unlocked=true;
+                }
+                ~relocker()
+                {
+                    if(unlocked)
+                    {
+                        lock.lock();
+                    }
+                    
+                }
+            };
+            
+
+        protected:
+            template<typename lock_type>
+            bool do_wait(lock_type& lock,::boost::system_time const& wait_until)
+            {
+                detail::win32::handle_manager local_wake_sem;
+                detail::win32::handle_manager sem;
+                bool first_loop=true;
+                bool woken=false;
+
+                relocker<lock_type> locker(lock);
+            
+                while(!woken)
+                {
+                    {
+                        boost::mutex::scoped_lock internal_lock(internal_mutex);
+                        detail::interlocked_write_release(&total_count,total_count+1);
+                        if(first_loop)
+                        {
+                            locker.unlock();
+                            if(!wake_sem)
+                            {
+                                wake_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+                                BOOST_ASSERT(wake_sem);
+                            }
+                            local_wake_sem=detail::win32::duplicate_handle(wake_sem);
+                        
+                            if(generations[0].notified)
+                            {
+                                shift_generations_down();
+                            }
+                            else if(!active_generation_count)
+                            {
+                                active_generation_count=1;
+                            }
+                        
+                            first_loop=false;
+                        }
+                        if(!generations[0].semaphore)
+                        {
+                            generations[0].semaphore=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+                            BOOST_ASSERT(generations[0].semaphore);
+                        }
+                        ++generations[0].count;
+                        sem=detail::win32::duplicate_handle(generations[0].semaphore);
+                    }
+                    unsigned long const wait_result=detail::win32::WaitForSingleObject(sem,::boost::detail::get_milliseconds_until(wait_until));
+
+                    if(wait_result==detail::win32::timeout)
+                    {
+                        break;
+                    }
+                    BOOST_ASSERT(!wait_result);
+                
+                    unsigned long const woken_result=detail::win32::WaitForSingleObject(local_wake_sem,0);
+                    BOOST_ASSERT(woken_result==detail::win32::timeout || woken_result==0);
+
+                    woken=(woken_result==0);
+                }
+                return woken;
+            }
+        
+            basic_condition_variable(const basic_condition_variable& other);
+            basic_condition_variable& operator=(const basic_condition_variable& other);
+        public:
+            basic_condition_variable():
+                total_count(0),active_generation_count(0),wake_sem(0)
+            {
+                for(unsigned i=0;i<generation_count;++i)
+                {
+                    generations[i]=list_entry();
+                }
+            }
+            
+            ~basic_condition_variable()
+            {
+                for(unsigned i=0;i<generation_count;++i)
+                {
+                    dispose_entry(generations[i]);
+                }
+                detail::win32::CloseHandle(wake_sem);
+            }
+
+        
+            void notify_one()
+            {
+                if(detail::interlocked_read_acquire(&total_count))
+                {
+                    boost::mutex::scoped_lock internal_lock(internal_mutex);
+                    detail::win32::ReleaseSemaphore(wake_sem,1,0);
+                    for(unsigned generation=active_generation_count;generation!=0;--generation)
+                    {
+                        list_entry& entry=generations[generation-1];
+                        if(entry.count)
+                        {
+                            detail::interlocked_write_release(&total_count,total_count-1);
+                            entry.notified=true;
+                            detail::win32::ReleaseSemaphore(entry.semaphore,1,0);
+                            if(!--entry.count)
+                            {
+                                dispose_entry(entry);
+                                if(generation==active_generation_count)
+                                {
+                                    --active_generation_count;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        
+            void notify_all()
+            {
+                if(detail::interlocked_read_acquire(&total_count))
+                {
+                    boost::mutex::scoped_lock internal_lock(internal_mutex);
+                    for(unsigned generation=active_generation_count;generation!=0;--generation)
+                    {
+                        list_entry& entry=generations[generation-1];
+                        if(entry.count)
+                        {
+                            broadcast_entry(entry,true);
+                        }
+                    }
+                    active_generation_count=0;
+                }
+            }
+        
+        };
+    }
+
+    class condition_variable:
+        public detail::basic_condition_variable
+    {
+    public:
+        void wait(unique_lock<mutex>& m)
+        {
+            do_wait(m,::boost::detail::get_system_time_sentinel());
+        }
+
+        template<typename predicate_type>
+        void wait(unique_lock<mutex>& m,predicate_type pred)
+        {
+            while(!pred()) wait(m);
+        }
+        
+
+        bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until)
+        {
+            return do_wait(m,wait_until);
+        }
+
+        template<typename predicate_type>
+        bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until,predicate_type pred)
+        {
+            while (!pred())
+            {
+                if(!timed_wait(m, wait_until))
+                    return false;
+            }
+            return true;
+        }
+    };
+    
+    class condition_variable_any:
+        public detail::basic_condition_variable
+    {
+    public:
+        template<typename lock_type>
+        void wait(lock_type& m)
+        {
+            do_wait(m,::boost::detail::get_system_time_sentinel());
+        }
+
+        template<typename lock_type,typename predicate_type>
+        void wait(lock_type& m,predicate_type pred)
+        {
+            while(!pred()) wait(m);
+        }
+        
+        template<typename lock_type>
+        bool timed_wait(lock_type& m,boost::system_time const& wait_until)
+        {
+            return do_wait(m,wait_until);
+        }
+
+        template<typename lock_type,typename predicate_type>
+        bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred)
+        {
+            while (!pred())
+            {
+                if(!timed_wait(m, wait_until))
+                    return false;
+            }
+            return true;
+        }
+    };
+
+}
+
+#endif
Modified: trunk/boost/thread/win32/interlocked_read.hpp
==============================================================================
--- trunk/boost/thread/win32/interlocked_read.hpp	(original)
+++ trunk/boost/thread/win32/interlocked_read.hpp	2007-10-19 13:40:04 EDT (Fri, 19 Oct 2007)
@@ -30,6 +30,17 @@
             _ReadWriteBarrier();
             return res;
         }
+
+        inline void interlocked_write_release(long volatile* x,long value)
+        {
+            _ReadWriteBarrier();
+            *x=value;
+        }
+        inline void interlocked_write_release(void* volatile* x,void* value)
+        {
+            _ReadWriteBarrier();
+            *x=value;
+        }
     }
 }
 
@@ -49,6 +60,14 @@
         {
             return BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(x,0,0);
         }
+        inline void interlocked_write_release(long volatile* x,long value)
+        {
+            BOOST_INTERLOCKED_EXCHANGE(x,value);
+        }
+        inline void interlocked_write_release(void* volatile* x,void* value)
+        {
+            BOOST_INTERLOCKED_EXCHANGE_POINTER(x,value);
+        }
     }
 }
 
Modified: trunk/boost/thread/xtime.hpp
==============================================================================
--- trunk/boost/thread/xtime.hpp	(original)
+++ trunk/boost/thread/xtime.hpp	2007-10-19 13:40:04 EDT (Fri, 19 Oct 2007)
@@ -1,5 +1,6 @@
 // Copyright (C) 2001-2003
 // William E. Kempf
+// Copyright (C) 2007 Anthony Williams
 //
 //  Distributed under the Boost Software License, Version 1.0. (See accompanying 
 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -39,6 +40,18 @@
 
     xtime_sec_t sec;
     xtime_nsec_t nsec;
+
+    operator system_time() const
+    {
+        return boost::posix_time::from_time_t(0)+
+            boost::posix_time::seconds(static_cast<long>(sec))+
+#ifdef BOOST_DATE_TIME_HAS_NANOSECONDS
+            boost::posix_time::nanoseconds(nsec);
+#else
+        boost::posix_time::microseconds((nsec+500)/1000);
+#endif
+    }
+    
 };
 
 int BOOST_THREAD_DECL xtime_get(struct xtime* xtp, int clock_type);
Modified: trunk/libs/thread/build/Jamfile.v2
==============================================================================
--- trunk/libs/thread/build/Jamfile.v2	(original)
+++ trunk/libs/thread/build/Jamfile.v2	2007-10-19 13:40:04 EDT (Fri, 19 Oct 2007)
@@ -14,8 +14,8 @@
     ;
 
 CPP_SOURCES =  
-        barrier
-        condition
+#        barrier
+#        condition
         exceptions
 #        mutex
 #        once
Deleted: trunk/libs/thread/src/barrier.cpp
==============================================================================
--- trunk/libs/thread/src/barrier.cpp	2007-10-19 13:40:04 EDT (Fri, 19 Oct 2007)
+++ (empty file)
@@ -1,42 +0,0 @@
-// Copyright (C) 2002-2003
-// David Moore, William E. Kempf
-//
-//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
-//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#include <boost/thread/detail/config.hpp>
-#include <boost/thread/barrier.hpp>
-#include <string> // see http://article.gmane.org/gmane.comp.lib.boost.devel/106981
-
-namespace boost {
-
-barrier::barrier(unsigned int count)
-    : m_threshold(count), m_count(count), m_generation(0)
-{
-    if (count == 0)
-        throw std::invalid_argument("count cannot be zero.");
-}
-
-barrier::~barrier()
-{
-}
-
-bool barrier::wait()
-{
-    boost::mutex::scoped_lock lock(m_mutex);
-    unsigned int gen = m_generation;
-
-    if (--m_count == 0)
-    {
-        m_generation++;
-        m_count = m_threshold;
-        m_cond.notify_all();
-        return true;
-    }
-
-    while (gen == m_generation)
-        m_cond.wait(lock);
-    return false;
-}
-
-} // namespace boost
Deleted: trunk/libs/thread/src/condition.cpp
==============================================================================
--- trunk/libs/thread/src/condition.cpp	2007-10-19 13:40:04 EDT (Fri, 19 Oct 2007)
+++ (empty file)
@@ -1,705 +0,0 @@
-// Copyright (C) 2001-2003
-// William E. Kempf
-//
-//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
-//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#include <boost/thread/detail/config.hpp>
-
-#include <boost/thread/condition.hpp>
-#include <boost/thread/xtime.hpp>
-#include <boost/thread/thread.hpp>
-#include <boost/thread/exceptions.hpp>
-#include <boost/limits.hpp>
-#include <cassert>
-#include "timeconv.inl"
-
-#if defined(BOOST_HAS_WINTHREADS)
-#   ifndef NOMINMAX
-#      define NOMINMAX
-#   endif
-#   include <windows.h>
-#elif defined(BOOST_HAS_PTHREADS)
-#   include <errno.h>
-#elif defined(BOOST_HAS_MPTASKS)
-#   include <MacErrors.h>
-#   include "mac/init.hpp"
-#   include "mac/safe.hpp"
-#endif
-
-// The following include can be removed after the bug on QNX
-// has been tracked down. I need this only for debugging
-//#if !defined(NDEBUG) && defined(BOOST_HAS_PTHREADS)
-#include <iostream>
-//#endif
-
-namespace boost {
-
-namespace detail {
-
-#if defined(BOOST_HAS_WINTHREADS)
-condition_impl::condition_impl()
-    : m_gone(0), m_blocked(0), m_waiting(0)
-{
-    m_gate = reinterpret_cast<void*>(CreateSemaphore(0, 1, 1, 0));
-    m_queue = reinterpret_cast<void*>(
-        CreateSemaphore(0, 0, (std::numeric_limits<long>::max)(), 0));
-    m_mutex = reinterpret_cast<void*>(CreateMutex(0, 0, 0));
-
-    if (!m_gate || !m_queue || !m_mutex)
-    {
-        int res = 0;
-        if (m_gate)
-        {
-            res = CloseHandle(reinterpret_cast<HANDLE>(m_gate));
-            assert(res);
-        }
-        if (m_queue)
-        {
-            res = CloseHandle(reinterpret_cast<HANDLE>(m_queue));
-            assert(res);
-        }
-        if (m_mutex)
-        {
-            res = CloseHandle(reinterpret_cast<HANDLE>(m_mutex));
-            assert(res);
-        }
-
-        throw thread_resource_error();
-    }
-}
-
-condition_impl::~condition_impl()
-{
-    int res = 0;
-    res = CloseHandle(reinterpret_cast<HANDLE>(m_gate));
-    assert(res);
-    res = CloseHandle(reinterpret_cast<HANDLE>(m_queue));
-    assert(res);
-    res = CloseHandle(reinterpret_cast<HANDLE>(m_mutex));
-    assert(res);
-}
-
-void condition_impl::notify_one()
-{
-    unsigned signals = 0;
-
-    int res = 0;
-    res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_mutex), INFINITE);
-    assert(res == WAIT_OBJECT_0);
-
-    if (m_waiting != 0) // the m_gate is already closed
-    {
-        if (m_blocked == 0)
-        {
-            res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex));
-            assert(res);
-            return;
-        }
-
-        ++m_waiting;
-        --m_blocked;
-        signals = 1;
-    }
-    else
-    {
-        res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_gate), INFINITE);
-        assert(res == WAIT_OBJECT_0);
-        if (m_blocked > m_gone)
-        {
-            if (m_gone != 0)
-            {
-                m_blocked -= m_gone;
-                m_gone = 0;
-            }
-            signals = m_waiting = 1;
-            --m_blocked;
-        }
-        else
-        {
-            res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
-            assert(res);
-        }
-    }
-
-    res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex));
-    assert(res);
-
-    if (signals)
-    {
-        res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_queue), signals, 0);
-        assert(res);
-    }
-}
-
-void condition_impl::notify_all()
-{
-    unsigned signals = 0;
-
-    int res = 0;
-    res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_mutex), INFINITE);
-    assert(res == WAIT_OBJECT_0);
-
-    if (m_waiting != 0) // the m_gate is already closed
-    {
-        if (m_blocked == 0)
-        {
-            res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex));
-            assert(res);
-            return;
-        }
-
-        m_waiting += (signals = m_blocked);
-        m_blocked = 0;
-    }
-    else
-    {
-        res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_gate), INFINITE);
-        assert(res == WAIT_OBJECT_0);
-        if (m_blocked > m_gone)
-        {
-            if (m_gone != 0)
-            {
-                m_blocked -= m_gone;
-                m_gone = 0;
-            }
-            signals = m_waiting = m_blocked;
-            m_blocked = 0;
-        }
-        else
-        {
-            res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
-            assert(res);
-        }
-    }
-
-    res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex));
-    assert(res);
-
-    if (signals)
-    {
-        res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_queue), signals, 0);
-        assert(res);
-    }
-}
-
-void condition_impl::enter_wait()
-{
-    int res = 0;
-    res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_gate), INFINITE);
-    assert(res == WAIT_OBJECT_0);
-    ++m_blocked;
-    res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
-    assert(res);
-}
-
-void condition_impl::do_wait()
-{
-    int res = 0;
-    res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue), INFINITE);
-    assert(res == WAIT_OBJECT_0);
-
-    unsigned was_waiting=0;
-    unsigned was_gone=0;
-
-    res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_mutex), INFINITE);
-    assert(res == WAIT_OBJECT_0);
-    was_waiting = m_waiting;
-    was_gone = m_gone;
-    if (was_waiting != 0)
-    {
-        if (--m_waiting == 0)
-        {
-            if (m_blocked != 0)
-            {
-                res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1,
-                    0); // open m_gate
-                assert(res);
-                was_waiting = 0;
-            }
-            else if (m_gone != 0)
-                m_gone = 0;
-        }
-    }
-    else if (++m_gone == ((std::numeric_limits<unsigned>::max)() / 2))
-    {
-        // timeout occured, normalize the m_gone count
-        // this may occur if many calls to wait with a timeout are made and
-        // no call to notify_* is made
-        res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_gate), INFINITE);
-        assert(res == WAIT_OBJECT_0);
-        m_blocked -= m_gone;
-        res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
-        assert(res);
-        m_gone = 0;
-    }
-    res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex));
-    assert(res);
-
-    if (was_waiting == 1)
-    {
-        for (/**/ ; was_gone; --was_gone)
-        {
-            // better now than spurious later
-            res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue),
-                INFINITE);
-            assert(res == WAIT_OBJECT_0);
-        }
-        res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
-        assert(res);
-    }
-}
-
-bool condition_impl::do_timed_wait(const xtime& xt)
-{
-    bool ret = false;
-    unsigned int res = 0;
-
-    for (;;)
-    {
-        int milliseconds;
-        to_duration(xt, milliseconds);
-
-        res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue),
-            milliseconds);
-        assert(res != WAIT_FAILED && res != WAIT_ABANDONED);
-        ret = (res == WAIT_OBJECT_0);
-
-        if (res == WAIT_TIMEOUT)
-        {
-            xtime cur;
-            xtime_get(&cur, TIME_UTC);
-            if (xtime_cmp(xt, cur) > 0)
-                continue;
-        }
-
-        break;
-    }
-
-    unsigned was_waiting=0;
-    unsigned was_gone=0;
-
-    res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_mutex), INFINITE);
-    assert(res == WAIT_OBJECT_0);
-    was_waiting = m_waiting;
-    was_gone = m_gone;
-    if (was_waiting != 0)
-    {
-        if (!ret) // timeout
-        {
-            if (m_blocked != 0)
-                --m_blocked;
-            else
-                ++m_gone; // count spurious wakeups
-        }
-        if (--m_waiting == 0)
-        {
-            if (m_blocked != 0)
-            {
-                res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1,
-                    0); // open m_gate
-                assert(res);
-                was_waiting = 0;
-            }
-            else if (m_gone != 0)
-                m_gone = 0;
-        }
-    }
-    else if (++m_gone == ((std::numeric_limits<unsigned>::max)() / 2))
-    {
-        // timeout occured, normalize the m_gone count
-        // this may occur if many calls to wait with a timeout are made and
-        // no call to notify_* is made
-        res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_gate), INFINITE);
-        assert(res == WAIT_OBJECT_0);
-        m_blocked -= m_gone;
-        res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
-        assert(res);
-        m_gone = 0;
-    }
-    res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex));
-    assert(res);
-
-    if (was_waiting == 1)
-    {
-        for (/**/ ; was_gone; --was_gone)
-        {
-            // better now than spurious later
-            res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue),
-                INFINITE);
-            assert(res ==  WAIT_OBJECT_0);
-        }
-        res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
-        assert(res);
-    }
-
-    return ret;
-}
-#elif defined(BOOST_HAS_PTHREADS)
-condition_impl::condition_impl()
-{
-    int res = 0;
-    res = pthread_cond_init(&m_condition, 0);
-    if (res != 0)
-        throw thread_resource_error();
-    res = pthread_mutex_init(&m_mutex, 0);
-    if (res != 0)
-        throw thread_resource_error();
-}
-
-condition_impl::~condition_impl()
-{
-    int res = 0;
-    res = pthread_cond_destroy(&m_condition);
-    assert(res == 0);
-    res = pthread_mutex_destroy(&m_mutex);
-    assert(res == 0);
-}
-
-void condition_impl::notify_one()
-{
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-    res = pthread_cond_signal(&m_condition);
-    assert(res == 0);
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-}
-
-void condition_impl::notify_all()
-{
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-    res = pthread_cond_broadcast(&m_condition);
-    assert(res == 0);
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-}
-
-void condition_impl::do_wait(pthread_mutex_t* pmutex)
-{
-    int res = 0;
-    res = pthread_cond_wait(&m_condition, pmutex);
-    assert(res == 0);
-}
-
-bool condition_impl::do_timed_wait(const xtime& xt, pthread_mutex_t* pmutex)
-{
-    timespec ts;
-    to_timespec(xt, ts);
-
-    int res = 0;
-    res = pthread_cond_timedwait(&m_condition, pmutex, &ts);
-// Test code for QNX debugging, to get information during regressions
-#ifndef NDEBUG
-    if (res == EINVAL) {
-        boost::xtime now;
-        boost::xtime_get(&now, boost::TIME_UTC);
-        std::cerr << "now: " << now.sec << " " << now.nsec << std::endl;
-        std::cerr << "time: " << time(0) << std::endl;
-        std::cerr << "xtime: " << xt.sec << " " << xt.nsec << std::endl;
-        std::cerr << "ts: " << ts.tv_sec << " " << ts.tv_nsec << std::endl;
-        std::cerr << "pmutex: " << pmutex << std::endl;
-        std::cerr << "condition: " << &m_condition << std::endl;
-        assert(res != EINVAL);
-    }
-#endif    
-    assert(res == 0 || res == ETIMEDOUT);
-
-    return res != ETIMEDOUT;
-}
-#elif defined(BOOST_HAS_MPTASKS)
-
-using threads::mac::detail::safe_enter_critical_region;
-using threads::mac::detail::safe_wait_on_semaphore;
-
-condition_impl::condition_impl()
-    : m_gone(0), m_blocked(0), m_waiting(0)
-{
-    threads::mac::detail::thread_init();
-
-    OSStatus lStatus = noErr;
-
-    lStatus = MPCreateSemaphore(1, 1, &m_gate);
-    if(lStatus == noErr)
-        lStatus = MPCreateSemaphore(ULONG_MAX, 0, &m_queue);
-
-    if(lStatus != noErr || !m_gate || !m_queue)
-    {
-        if (m_gate)
-        {
-            lStatus = MPDeleteSemaphore(m_gate);
-            assert(lStatus == noErr);
-        }
-        if (m_queue)
-        {
-            lStatus = MPDeleteSemaphore(m_queue);
-            assert(lStatus == noErr);
-        }
-
-        throw thread_resource_error();
-    }
-}
-
-condition_impl::~condition_impl()
-{
-    OSStatus lStatus = noErr;
-    lStatus = MPDeleteSemaphore(m_gate);
-    assert(lStatus == noErr);
-    lStatus = MPDeleteSemaphore(m_queue);
-    assert(lStatus == noErr);
-}
-
-void condition_impl::notify_one()
-{
-    unsigned signals = 0;
-
-    OSStatus lStatus = noErr;
-    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
-        m_mutex_mutex);
-    assert(lStatus == noErr);
-
-    if (m_waiting != 0) // the m_gate is already closed
-    {
-        if (m_blocked == 0)
-        {
-            lStatus = MPExitCriticalRegion(m_mutex);
-            assert(lStatus == noErr);
-            return;
-        }
-
-        ++m_waiting;
-        --m_blocked;
-    }
-    else
-    {
-        lStatus = safe_wait_on_semaphore(m_gate, kDurationForever);
-        assert(lStatus == noErr);
-        if (m_blocked > m_gone)
-        {
-            if (m_gone != 0)
-            {
-                m_blocked -= m_gone;
-                m_gone = 0;
-            }
-            signals = m_waiting = 1;
-            --m_blocked;
-        }
-        else
-        {
-            lStatus = MPSignalSemaphore(m_gate);
-            assert(lStatus == noErr);
-        }
-
-        lStatus = MPExitCriticalRegion(m_mutex);
-        assert(lStatus == noErr);
-
-        while (signals)
-        {
-            lStatus = MPSignalSemaphore(m_queue);
-            assert(lStatus == noErr);
-            --signals;
-        }
-    }
-}
-
-void condition_impl::notify_all()
-{
-    unsigned signals = 0;
-
-    OSStatus lStatus = noErr;
-    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
-        m_mutex_mutex);
-    assert(lStatus == noErr);
-
-    if (m_waiting != 0) // the m_gate is already closed
-    {
-        if (m_blocked == 0)
-        {
-            lStatus = MPExitCriticalRegion(m_mutex);
-            assert(lStatus == noErr);
-            return;
-        }
-
-        m_waiting += (signals = m_blocked);
-        m_blocked = 0;
-    }
-    else
-    {
-        lStatus = safe_wait_on_semaphore(m_gate, kDurationForever);
-        assert(lStatus == noErr);
-        if (m_blocked > m_gone)
-        {
-            if (m_gone != 0)
-            {
-                m_blocked -= m_gone;
-                m_gone = 0;
-            }
-            signals = m_waiting = m_blocked;
-            m_blocked = 0;
-        }
-        else
-        {
-            lStatus = MPSignalSemaphore(m_gate);
-            assert(lStatus == noErr);
-        }
-
-        lStatus = MPExitCriticalRegion(m_mutex);
-        assert(lStatus == noErr);
-
-        while (signals)
-        {
-            lStatus = MPSignalSemaphore(m_queue);
-            assert(lStatus == noErr);
-            --signals;
-        }
-    }
-}
-
-void condition_impl::enter_wait()
-{
-    OSStatus lStatus = noErr;
-    lStatus = safe_wait_on_semaphore(m_gate, kDurationForever);
-    assert(lStatus == noErr);
-    ++m_blocked;
-    lStatus = MPSignalSemaphore(m_gate);
-    assert(lStatus == noErr);
-}
-
-void condition_impl::do_wait()
-{
-    OSStatus lStatus = noErr;
-    lStatus = safe_wait_on_semaphore(m_queue, kDurationForever);
-    assert(lStatus == noErr);
-
-    unsigned was_waiting=0;
-    unsigned was_gone=0;
-
-    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
-        m_mutex_mutex);
-    assert(lStatus == noErr);
-    was_waiting = m_waiting;
-    was_gone = m_gone;
-    if (was_waiting != 0)
-    {
-        if (--m_waiting == 0)
-        {
-            if (m_blocked != 0)
-            {
-                lStatus = MPSignalSemaphore(m_gate); // open m_gate
-                assert(lStatus == noErr);
-                was_waiting = 0;
-            }
-            else if (m_gone != 0)
-                m_gone = 0;
-        }
-    }
-    else if (++m_gone == ((std::numeric_limits<unsigned>::max)() / 2))
-    {
-        // timeout occured, normalize the m_gone count
-        // this may occur if many calls to wait with a timeout are made and
-        // no call to notify_* is made
-        lStatus = safe_wait_on_semaphore(m_gate, kDurationForever);
-        assert(lStatus == noErr);
-        m_blocked -= m_gone;
-        lStatus = MPSignalSemaphore(m_gate);
-        assert(lStatus == noErr);
-        m_gone = 0;
-    }
-    lStatus = MPExitCriticalRegion(m_mutex);
-    assert(lStatus == noErr);
-
-    if (was_waiting == 1)
-    {
-        for (/**/ ; was_gone; --was_gone)
-        {
-            // better now than spurious later
-            lStatus = safe_wait_on_semaphore(m_queue, kDurationForever);
-            assert(lStatus == noErr);
-        }
-        lStatus = MPSignalSemaphore(m_gate);
-        assert(lStatus == noErr);
-    }
-}
-
-bool condition_impl::do_timed_wait(const xtime& xt)
-{
-    int milliseconds;
-    to_duration(xt, milliseconds);
-
-    OSStatus lStatus = noErr;
-    lStatus = safe_wait_on_semaphore(m_queue, milliseconds);
-    assert(lStatus == noErr || lStatus == kMPTimeoutErr);
-
-    bool ret = (lStatus == noErr);
-
-    unsigned was_waiting=0;
-    unsigned was_gone=0;
-
-    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
-        m_mutex_mutex);
-    assert(lStatus == noErr);
-    was_waiting = m_waiting;
-    was_gone = m_gone;
-    if (was_waiting != 0)
-    {
-        if (!ret) // timeout
-        {
-            if (m_blocked != 0)
-                --m_blocked;
-            else
-                ++m_gone; // count spurious wakeups
-        }
-        if (--m_waiting == 0)
-        {
-            if (m_blocked != 0)
-            {
-                lStatus = MPSignalSemaphore(m_gate); // open m_gate
-                assert(lStatus == noErr);
-                was_waiting = 0;
-            }
-            else if (m_gone != 0)
-                m_gone = 0;
-        }
-    }
-    else if (++m_gone == ((std::numeric_limits<unsigned>::max)() / 2))
-    {
-        // timeout occured, normalize the m_gone count
-        // this may occur if many calls to wait with a timeout are made and
-        // no call to notify_* is made
-        lStatus = safe_wait_on_semaphore(m_gate, kDurationForever);
-        assert(lStatus == noErr);
-        m_blocked -= m_gone;
-        lStatus = MPSignalSemaphore(m_gate);
-        assert(lStatus == noErr);
-        m_gone = 0;
-    }
-    lStatus = MPExitCriticalRegion(m_mutex);
-    assert(lStatus == noErr);
-
-    if (was_waiting == 1)
-    {
-        for (/**/ ; was_gone; --was_gone)
-        {
-            // better now than spurious later
-            lStatus = safe_wait_on_semaphore(m_queue, kDurationForever);
-            assert(lStatus == noErr);
-        }
-        lStatus = MPSignalSemaphore(m_gate);
-        assert(lStatus == noErr);
-    }
-
-    return ret;
-}
-#endif
-
-} // namespace detail
-
-} // namespace boost
-
-// Change Log:
-//    8 Feb 01  WEKEMPF Initial version.
-//   22 May 01  WEKEMPF Modified to use xtime for time outs.
-//    3 Jan 03  WEKEMPF Modified for DLL implementation.