$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: anthony_at_[hidden]
Date: 2007-10-10 11:33:51
Author: anthonyw
Date: 2007-10-10 11:33:49 EDT (Wed, 10 Oct 2007)
New Revision: 39891
URL: http://svn.boost.org/trac/boost/changeset/39891
Log:
read_write_mutex makes a comeback --- as shared_mutex
Added:
   trunk/boost/thread/pthread/shared_mutex.hpp   (contents, props changed)
   trunk/boost/thread/shared_mutex.hpp   (contents, props changed)
   trunk/boost/thread/win32/shared_mutex.hpp   (contents, props changed)
   trunk/libs/thread/test/test_lock_concept.cpp   (contents, props changed)
   trunk/libs/thread/test/test_shared_mutex.cpp   (contents, props changed)
Removed:
   trunk/libs/thread/src/mutex.cpp
   trunk/libs/thread/src/mutex.inl
   trunk/libs/thread/src/once.cpp
   trunk/libs/thread/src/recursive_mutex.cpp
Text files modified: 
   trunk/boost/thread/locks.hpp                   |   162 ++++++++++++++++++++++++--------------- 
   trunk/boost/thread/thread_time.hpp             |     2                                         
   trunk/boost/thread/win32/thread_primitives.hpp |     3                                         
   trunk/boost/thread/xtime.hpp                   |    12 ++                                      
   trunk/libs/thread/test/Jamfile.v2              |     3                                         
   5 files changed, 115 insertions(+), 67 deletions(-)
Modified: trunk/boost/thread/locks.hpp
==============================================================================
--- trunk/boost/thread/locks.hpp	(original)
+++ trunk/boost/thread/locks.hpp	2007-10-10 11:33:49 EDT (Wed, 10 Oct 2007)
@@ -24,13 +24,13 @@
     const adopt_lock_t adopt_lock={};
 
     template<typename Mutex>
-    class shareable_lock;
+    class shared_lock;
 
     template<typename Mutex>
     class exclusive_lock;
 
     template<typename Mutex>
-    class upgradeable_lock;
+    class upgrade_lock;
 
     template<typename Mutex>
     class lock_guard
@@ -86,21 +86,21 @@
         {
             timed_lock(target_time);
         }
-        unique_lock(boost::move_t<unique_lock> other):
+        unique_lock(boost::move_t<unique_lock<Mutex> > other):
             m(other->m),is_locked(other->is_locked)
         {
             other->is_locked=false;
         }
-        unique_lock(boost::move_t<upgradeable_lock<Mutex> > other);
+        unique_lock(boost::move_t<upgrade_lock<Mutex> > other);
 
-        unique_lock& operator=(boost::move_t<unique_lock> other)
+        unique_lock& operator=(boost::move_t<unique_lock<Mutex> > other)
         {
             unique_lock temp(other);
             swap(temp);
             return *this;
         }
 
-        unique_lock& operator=(boost::move_t<upgradeable_lock<Mutex> > other)
+        unique_lock& operator=(boost::move_t<upgrade_lock<Mutex> > other)
         {
             unique_lock temp(other);
             swap(temp);
@@ -112,7 +112,7 @@
             std::swap(m,other.m);
             std::swap(is_locked,other.is_locked);
         }
-        void swap(boost::move_t<unique_lock> other)
+        void swap(boost::move_t<unique_lock<Mutex> > other)
         {
             std::swap(m,other->m);
             std::swap(is_locked,other->is_locked);
@@ -170,6 +170,10 @@
         {
             return is_locked?&unique_lock::lock:0;
         }
+        bool operator!() const
+        {
+            return !owns_lock();
+        }
         bool owns_lock() const
         {
             return is_locked;
@@ -188,91 +192,100 @@
             return res;
         }
 
-        friend class shareable_lock<Mutex>;
-        friend class upgradeable_lock<Mutex>;
+        friend class shared_lock<Mutex>;
+        friend class upgrade_lock<Mutex>;
     };
 
     template<typename Mutex>
-    class shareable_lock
+    class shared_lock
     {
     protected:
         Mutex* m;
         bool is_locked;
     private:
-        explicit shareable_lock(shareable_lock&);
-        shareable_lock& operator=(shareable_lock&);
+        explicit shared_lock(shared_lock&);
+        shared_lock& operator=(shared_lock&);
     public:
-        explicit shareable_lock(Mutex& m_):
+        explicit shared_lock(Mutex& m_):
             m(&m_),is_locked(false)
         {
             lock();
         }
-        shareable_lock(Mutex& m_,bool do_lock):
+        shared_lock(Mutex& m_,adopt_lock_t):
+            m(&m_),is_locked(true)
+        {}
+        shared_lock(Mutex& m_,defer_lock_t):
+            m(&m_),is_locked(false)
+        {}
+        shared_lock(Mutex& m_,try_to_lock_t):
             m(&m_),is_locked(false)
         {
-            if(do_lock)
-            {
-                lock();
-            }
+            try_lock();
+        }
+        shared_lock(Mutex& m_,system_time const& target_time):
+            m(&m_),is_locked(false)
+        {
+            timed_lock(target_time);
         }
-        shareable_lock(boost::move_t<shareable_lock> other):
+
+        shared_lock(boost::move_t<shared_lock<Mutex> > other):
             m(other->m),is_locked(other->is_locked)
         {
             other->is_locked=false;
         }
 
-        shareable_lock(boost::move_t<unique_lock<Mutex> > other):
+        shared_lock(boost::move_t<unique_lock<Mutex> > other):
             m(other->m),is_locked(other->is_locked)
         {
             other->is_locked=false;
             if(is_locked)
             {
-                m->unlock_and_lock_shareable();
+                m->unlock_and_lock_shared();
             }
         }
 
-        shareable_lock(boost::move_t<upgradeable_lock<Mutex> > other):
+        shared_lock(boost::move_t<upgrade_lock<Mutex> > other):
             m(other->m),is_locked(other->is_locked)
         {
             other->is_locked=false;
             if(is_locked)
             {
-                m->unlock_upgradeable_and_lock_shareable();
+                m->unlock_upgrade_and_lock_shared();
             }
         }
 
-        shareable_lock& operator=(boost::move_t<shareable_lock> other)
+        shared_lock& operator=(boost::move_t<shared_lock<Mutex> > other)
         {
-            shareable_lock temp(other);
+            shared_lock temp(other);
             swap(temp);
             return *this;
         }
 
-        shareable_lock& operator=(boost::move_t<unique_lock<Mutex> > other)
+        shared_lock& operator=(boost::move_t<unique_lock<Mutex> > other)
         {
-            shareable_lock temp(other);
+            shared_lock temp(other);
             swap(temp);
             return *this;
         }
 
-        shareable_lock& operator=(boost::move_t<upgradeable_lock<Mutex> > other)
+        shared_lock& operator=(boost::move_t<upgrade_lock<Mutex> > other)
         {
-            shareable_lock temp(other);
+            shared_lock temp(other);
             swap(temp);
             return *this;
         }
 
-        void swap(shareable_lock& other)
+        void swap(shared_lock& other)
         {
             std::swap(m,other.m);
             std::swap(is_locked,other.is_locked);
         }
         
-        ~shareable_lock()
+        ~shared_lock()
         {
             if(owns_lock())
             {
-                m->unlock_shareable();
+                m->unlock_shared();
             }
         }
         void lock()
@@ -281,7 +294,7 @@
             {
                 throw boost::lock_error();
             }
-            m->lock_shareable();
+            m->lock_shared();
             is_locked=true;
         }
         bool try_lock()
@@ -290,7 +303,16 @@
             {
                 throw boost::lock_error();
             }
-            is_locked=m->try_lock_shareable();
+            is_locked=m->try_lock_shared();
+            return is_locked;
+        }
+        bool timed_lock(boost::system_time const& target_time)
+        {
+            if(owns_lock())
+            {
+                throw boost::lock_error();
+            }
+            is_locked=m->timed_lock_shared(target_time);
             return is_locked;
         }
         void unlock()
@@ -299,14 +321,18 @@
             {
                 throw boost::lock_error();
             }
-            m->unlock_shareable();
+            m->unlock_shared();
             is_locked=false;
         }
             
-        typedef void (shareable_lock::*bool_type)();
+        typedef void (shared_lock::*bool_type)();
         operator bool_type() const
         {
-            return is_locked?&shareable_lock::lock:0;
+            return is_locked?&shared_lock::lock:0;
+        }
+        bool operator!() const
+        {
+            return !owns_lock();
         }
         bool owns_lock() const
         {
@@ -316,21 +342,21 @@
     };
 
     template<typename Mutex>
-    class upgradeable_lock
+    class upgrade_lock
     {
     protected:
         Mutex* m;
         bool is_locked;
     private:
-        explicit upgradeable_lock(upgradeable_lock&);
-        upgradeable_lock& operator=(upgradeable_lock&);
+        explicit upgrade_lock(upgrade_lock&);
+        upgrade_lock& operator=(upgrade_lock&);
     public:
-        explicit upgradeable_lock(Mutex& m_):
+        explicit upgrade_lock(Mutex& m_):
             m(&m_),is_locked(false)
         {
             lock();
         }
-        upgradeable_lock(Mutex& m_,bool do_lock):
+        upgrade_lock(Mutex& m_,bool do_lock):
             m(&m_),is_locked(false)
         {
             if(do_lock)
@@ -338,47 +364,47 @@
                 lock();
             }
         }
-        upgradeable_lock(boost::move_t<upgradeable_lock> other):
+        upgrade_lock(boost::move_t<upgrade_lock<Mutex> > other):
             m(other->m),is_locked(other->is_locked)
         {
             other->is_locked=false;
         }
 
-        upgradeable_lock(boost::move_t<unique_lock<Mutex> > other):
+        upgrade_lock(boost::move_t<unique_lock<Mutex> > other):
             m(other->m),is_locked(other->is_locked)
         {
             other->is_locked=false;
             if(is_locked)
             {
-                m->unlock_and_lock_upgradeable();
+                m->unlock_and_lock_upgrade();
             }
         }
 
-        upgradeable_lock& operator=(boost::move_t<upgradeable_lock> other)
+        upgrade_lock& operator=(boost::move_t<upgrade_lock<Mutex> > other)
         {
-            upgradeable_lock temp(other);
+            upgrade_lock temp(other);
             swap(temp);
             return *this;
         }
 
-        upgradeable_lock& operator=(boost::move_t<unique_lock<Mutex> > other)
+        upgrade_lock& operator=(boost::move_t<unique_lock<Mutex> > other)
         {
-            upgradeable_lock temp(other);
+            upgrade_lock temp(other);
             swap(temp);
             return *this;
         }
 
-        void swap(upgradeable_lock& other)
+        void swap(upgrade_lock& other)
         {
             std::swap(m,other.m);
             std::swap(is_locked,other.is_locked);
         }
         
-        ~upgradeable_lock()
+        ~upgrade_lock()
         {
             if(owns_lock())
             {
-                m->unlock_upgradeable();
+                m->unlock_upgrade();
             }
         }
         void lock()
@@ -387,7 +413,7 @@
             {
                 throw boost::lock_error();
             }
-            m->lock_upgradeable();
+            m->lock_upgrade();
             is_locked=true;
         }
         bool try_lock()
@@ -396,7 +422,7 @@
             {
                 throw boost::lock_error();
             }
-            is_locked=m->try_lock_upgradeable();
+            is_locked=m->try_lock_upgrade();
             return is_locked;
         }
         void unlock()
@@ -405,31 +431,35 @@
             {
                 throw boost::lock_error();
             }
-            m->unlock_upgradeable();
+            m->unlock_upgrade();
             is_locked=false;
         }
             
-        typedef void (upgradeable_lock::*bool_type)();
+        typedef void (upgrade_lock::*bool_type)();
         operator bool_type() const
         {
-            return is_locked?&upgradeable_lock::lock:0;
+            return is_locked?&upgrade_lock::lock:0;
+        }
+        bool operator!() const
+        {
+            return !owns_lock();
         }
         bool owns_lock() const
         {
             return is_locked;
         }
-        friend class shareable_lock<Mutex>;
+        friend class shared_lock<Mutex>;
         friend class unique_lock<Mutex>;
     };
 
     template<typename Mutex>
-    unique_lock<Mutex>::unique_lock(boost::move_t<upgradeable_lock<Mutex> > other):
+    unique_lock<Mutex>::unique_lock(boost::move_t<upgrade_lock<Mutex> > other):
         m(other->m),is_locked(other->is_locked)
     {
         other->is_locked=false;
         if(is_locked)
         {
-            m->unlock_upgradeable_and_lock();
+            m->unlock_upgrade_and_lock();
         }
     }
 
@@ -437,13 +467,13 @@
     class upgrade_to_unique_lock
     {
     private:
-        upgradeable_lock<Mutex>* source;
+        upgrade_lock<Mutex>* source;
         unique_lock<Mutex> exclusive;
 
         explicit upgrade_to_unique_lock(upgrade_to_unique_lock&);
         upgrade_to_unique_lock& operator=(upgrade_to_unique_lock&);
     public:
-        explicit upgrade_to_unique_lock(upgradeable_lock<Mutex>& m_):
+        explicit upgrade_to_unique_lock(upgrade_lock<Mutex>& m_):
             source(&m_),exclusive(boost::move(*source))
         {}
         ~upgrade_to_unique_lock()
@@ -454,13 +484,13 @@
             }
         }
 
-        upgrade_to_unique_lock(boost::move_t<upgrade_to_unique_lock> other):
+        upgrade_to_unique_lock(boost::move_t<upgrade_to_unique_lock<Mutex> > other):
             source(other->source),exclusive(boost::move(other->exclusive))
         {
             other->source=0;
         }
         
-        upgrade_to_unique_lock& operator=(boost::move_t<upgrade_to_unique_lock> other)
+        upgrade_to_unique_lock& operator=(boost::move_t<upgrade_to_unique_lock<Mutex> > other)
         {
             upgrade_to_unique_lock temp(other);
             swap(temp);
@@ -476,6 +506,10 @@
         {
             return exclusive.owns_lock()?&upgrade_to_unique_lock::swap:0;
         }
+        bool operator!() const
+        {
+            return !owns_lock();
+        }
         bool owns_lock() const
         {
             return exclusive.owns_lock();
Added: trunk/boost/thread/pthread/shared_mutex.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/pthread/shared_mutex.hpp	2007-10-10 11:33:49 EDT (Wed, 10 Oct 2007)
@@ -0,0 +1,300 @@
+#ifndef BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
+#define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
+
+//  (C) Copyright 2006-7 Anthony Williams
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/xtime.hpp>
+
+namespace boost
+{
+    class shared_mutex
+    {
+    private:
+        struct state_data
+        {
+            unsigned shared_count;
+            bool exclusive;
+            bool upgrade;
+            bool exclusive_waiting_blocked;
+        };
+        
+
+
+        state_data state;
+        boost::mutex state_change;
+        boost::condition shared_cond;
+        boost::condition exclusive_cond;
+        boost::condition upgrade_cond;
+
+        void release_waiters()
+        {
+            exclusive_cond.notify_one();
+            shared_cond.notify_all();
+        }
+        
+
+    public:
+        shared_mutex()
+        {
+            state_data state_={0};
+            state=state_;
+        }
+
+        ~shared_mutex()
+        {
+        }
+
+        void lock_shared()
+        {
+            boost::mutex::scoped_lock lock(state_change);
+                
+            while(true)
+            {
+                if(!state.exclusive && !state.exclusive_waiting_blocked)
+                {
+                    ++state.shared_count;
+                    return;
+                }
+                
+                shared_cond.wait(lock);
+            }
+        }
+
+        bool try_lock_shared()
+        {
+            boost::mutex::scoped_lock lock(state_change);
+                
+            if(state.exclusive || state.exclusive_waiting_blocked)
+            {
+                return false;
+            }
+            else
+            {
+                ++state.shared_count;
+                return true;
+            }
+        }
+
+        bool timed_lock_shared(system_time const& timeout)
+        {
+            boost::mutex::scoped_lock lock(state_change);
+                
+            while(true)
+            {
+                if(!state.exclusive && !state.exclusive_waiting_blocked)
+                {
+                    ++state.shared_count;
+                    return true;
+                }
+                
+                if(!shared_cond.timed_wait(lock,get_xtime(timeout)))
+                {
+                    return false;
+                }
+            }
+        }
+
+        void unlock_shared()
+        {
+            boost::mutex::scoped_lock lock(state_change);
+            bool const last_reader=!--state.shared_count;
+                
+            if(last_reader)
+            {
+                if(state.upgrade)
+                {
+                    state.upgrade=false;
+                    state.exclusive=true;
+                    upgrade_cond.notify_one();
+                }
+                else
+                {
+                    state.exclusive_waiting_blocked=false;
+                }
+                release_waiters();
+            }
+        }
+
+        void lock()
+        {
+            boost::mutex::scoped_lock lock(state_change);
+                
+            while(true)
+            {
+                if(state.shared_count || state.exclusive)
+                {
+                    state.exclusive_waiting_blocked=true;
+                }
+                else
+                {
+                    state.exclusive=true;
+                    return;
+                }
+                exclusive_cond.wait(lock);
+            }
+        }
+
+        bool timed_lock(system_time const& timeout)
+        {
+            boost::mutex::scoped_lock lock(state_change);
+                
+            while(true)
+            {
+                if(state.shared_count || state.exclusive)
+                {
+                    state.exclusive_waiting_blocked=true;
+                }
+                else
+                {
+                    state.exclusive=true;
+                    return true;
+                }
+                if(!exclusive_cond.timed_wait(lock,get_xtime(timeout)))
+                {
+                    return false;
+                }
+            }
+        }
+
+        bool try_lock()
+        {
+            boost::mutex::scoped_lock lock(state_change);
+                
+            if(state.shared_count || state.exclusive)
+            {
+                return false;
+            }
+            else
+            {
+                state.exclusive=true;
+                return true;
+            }
+                
+        }
+
+        void unlock()
+        {
+            boost::mutex::scoped_lock lock(state_change);
+            state.exclusive=false;
+            state.exclusive_waiting_blocked=false;
+            release_waiters();
+        }
+
+        void lock_upgrade()
+        {
+            boost::mutex::scoped_lock lock(state_change);
+            while(true)
+            {
+                if(!state.exclusive && !state.exclusive_waiting_blocked && !state.upgrade)
+                {
+                    ++state.shared_count;
+                    state.upgrade=true;
+                    return;
+                }
+                
+                shared_cond.wait(lock);
+            }
+        }
+
+        bool timed_lock_upgrade(system_time const& timeout)
+        {
+            boost::mutex::scoped_lock lock(state_change);
+            while(true)
+            {
+                if(!state.exclusive && !state.exclusive_waiting_blocked && !state.upgrade)
+                {
+                    ++state.shared_count;
+                    state.upgrade=true;
+                    return true;
+                }
+                
+                if(!shared_cond.timed_wait(lock,get_xtime(timeout)))
+                {
+                    return false;
+                }
+            }
+        }
+
+        bool try_lock_upgrade()
+        {
+            boost::mutex::scoped_lock lock(state_change);
+            if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+            {
+                return false;
+            }
+            else
+            {
+                ++state.shared_count;
+                state.upgrade=true;
+                return true;
+            }
+        }
+
+        void unlock_upgrade()
+        {
+            boost::mutex::scoped_lock lock(state_change);
+            state.upgrade=false;
+            bool const last_reader=!--state.shared_count;
+                
+            if(last_reader)
+            {
+                state.exclusive_waiting_blocked=false;
+                release_waiters();
+            }
+        }
+
+        void unlock_upgrade_and_lock()
+        {
+            boost::mutex::scoped_lock lock(state_change);
+            --state.shared_count;
+            while(true)
+            {
+                if(!state.shared_count)
+                {
+                    state.upgrade=false;
+                    state.exclusive=true;
+                    break;
+                }
+                upgrade_cond.wait(lock);
+            }
+        }
+
+        void unlock_and_lock_upgrade()
+        {
+            boost::mutex::scoped_lock lock(state_change);
+            state.exclusive=false;
+            state.upgrade=true;
+            ++state.shared_count;
+            state.exclusive_waiting_blocked=false;
+            release_waiters();
+        }
+        
+        void unlock_and_lock_shared()
+        {
+            boost::mutex::scoped_lock lock(state_change);
+            state.exclusive=false;
+            ++state.shared_count;
+            state.exclusive_waiting_blocked=false;
+            release_waiters();
+        }
+        
+        void unlock_upgrade_and_lock_shared()
+        {
+            boost::mutex::scoped_lock lock(state_change);
+            state.upgrade=false;
+            state.exclusive_waiting_blocked=false;
+            release_waiters();
+        }
+    };
+}
+
+
+#endif
Added: trunk/boost/thread/shared_mutex.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/shared_mutex.hpp	2007-10-10 11:33:49 EDT (Wed, 10 Oct 2007)
@@ -0,0 +1,15 @@
+#ifndef BOOST_THREAD_SHARED_MUTEX_HPP
+#define BOOST_THREAD_SHARED_MUTEX_HPP
+
+//  shared_mutex.hpp
+//
+//  (C) Copyright 2007 Anthony Williams 
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/thread/detail/platform.hpp>
+#include BOOST_THREAD_PLATFORM(shared_mutex.hpp)
+
+#endif
Modified: trunk/boost/thread/thread_time.hpp
==============================================================================
--- trunk/boost/thread/thread_time.hpp	(original)
+++ trunk/boost/thread/thread_time.hpp	2007-10-10 11:33:49 EDT (Wed, 10 Oct 2007)
@@ -30,7 +30,7 @@
             {
                 return 0;
             }
-            return (target_time-now).total_milliseconds();
+            return (target_time-now).total_milliseconds()+1;
         }
 
     }
Added: trunk/boost/thread/win32/shared_mutex.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/win32/shared_mutex.hpp	2007-10-10 11:33:49 EDT (Wed, 10 Oct 2007)
@@ -0,0 +1,516 @@
+#ifndef BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
+#define BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
+
+//  (C) Copyright 2006-7 Anthony Williams
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/assert.hpp>
+#include <boost/detail/interlocked.hpp>
+#include <boost/thread/win32/thread_primitives.hpp>
+#include <boost/static_assert.hpp>
+#include <limits.h>
+#include <boost/utility.hpp>
+#include <boost/thread/thread_time.hpp>
+
+namespace boost
+{
+    class shared_mutex:
+        private boost::noncopyable
+    {
+    private:
+        struct state_data
+        {
+            unsigned shared_count:11;
+            unsigned shared_waiting:11;
+            unsigned exclusive:1;
+            unsigned upgrade:1;
+            unsigned exclusive_waiting:7;
+            unsigned exclusive_waiting_blocked:1;
+
+            friend bool operator==(state_data const& lhs,state_data const& rhs)
+            {
+                return *reinterpret_cast<unsigned const*>(&lhs)==*reinterpret_cast<unsigned const*>(&rhs);
+            }
+        };
+        
+
+        template<typename T>
+        T interlocked_compare_exchange(T* target,T new_value,T comparand)
+        {
+            BOOST_STATIC_ASSERT(sizeof(T)==sizeof(long));
+            long const res=BOOST_INTERLOCKED_COMPARE_EXCHANGE(reinterpret_cast<long*>(target),
+                                                              *reinterpret_cast<long*>(&new_value),
+                                                              *reinterpret_cast<long*>(&comparand));
+            return *reinterpret_cast<T const*>(&res);
+        }
+
+        state_data state;
+        void* semaphores[2];
+        void* &unlock_sem;
+        void* &exclusive_sem;
+        void* upgrade_sem;
+
+        void release_waiters(state_data old_state)
+        {
+            if(old_state.exclusive_waiting)
+            {
+                bool const success=detail::win32::ReleaseSemaphore(exclusive_sem,1,NULL)!=0;
+                BOOST_ASSERT(success);
+            }
+                        
+            if(old_state.shared_waiting || old_state.exclusive_waiting)
+            {
+                bool const success=detail::win32::ReleaseSemaphore(unlock_sem,old_state.shared_waiting + (old_state.exclusive_waiting?1:0),NULL)!=0;
+                BOOST_ASSERT(success);
+            }
+        }
+        
+
+    public:
+        shared_mutex():
+            unlock_sem(semaphores[0]),
+            exclusive_sem(semaphores[1]) 
+        {
+            unlock_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+            exclusive_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+            upgrade_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+            state_data state_={0};
+            state=state_;
+        }
+
+        ~shared_mutex()
+        {
+            detail::win32::CloseHandle(upgrade_sem);
+            detail::win32::CloseHandle(unlock_sem);
+            detail::win32::CloseHandle(exclusive_sem);
+        }
+
+        bool try_lock_shared()
+        {
+            state_data old_state=state;
+            do
+            {
+                state_data new_state=old_state;
+                if(!new_state.exclusive && !new_state.exclusive_waiting_blocked)
+                {
+                    ++new_state.shared_count;
+                }
+                
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    break;
+                }
+                old_state=current_state;
+            }
+            while(true);
+            return !(old_state.exclusive| old_state.exclusive_waiting_blocked);
+        }
+
+        void lock_shared()
+        {
+            bool const success=timed_lock_shared(::boost::detail::get_system_time_sentinel());
+            BOOST_ASSERT(success);
+        }
+
+        bool timed_lock_shared(boost::system_time const& wait_until)
+        {
+            while(true)
+            {
+                state_data old_state=state;
+                do
+                {
+                    state_data new_state=old_state;
+                    if(new_state.exclusive || new_state.exclusive_waiting_blocked)
+                    {
+                        ++new_state.shared_waiting;
+                    }
+                    else
+                    {
+                        ++new_state.shared_count;
+                    }
+
+                    state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                    if(current_state==old_state)
+                    {
+                        break;
+                    }
+                    old_state=current_state;
+                }
+                while(true);
+
+                if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
+                {
+                    return true;
+                }
+                    
+                unsigned long const res=detail::win32::WaitForSingleObject(unlock_sem,::boost::detail::get_milliseconds_until(wait_until));
+                if(res==detail::win32::timeout)
+                {
+                    do
+                    {
+                        state_data new_state=old_state;
+                        if(new_state.exclusive || new_state.exclusive_waiting_blocked)
+                        {
+                            if(new_state.shared_waiting)
+                            {
+                                --new_state.shared_waiting;
+                            }
+                        }
+                        else
+                        {
+                            ++new_state.shared_count;
+                        }
+
+                        state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                        if(current_state==old_state)
+                        {
+                            break;
+                        }
+                        old_state=current_state;
+                    }
+                    while(true);
+
+                    if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
+                    {
+                        return true;
+                    }
+                    return false;
+                }
+                
+                BOOST_ASSERT(res==0);
+            }
+        }
+
+        void unlock_shared()
+        {
+            state_data old_state=state;
+            do
+            {
+                state_data new_state=old_state;
+                bool const last_reader=!--new_state.shared_count;
+                
+                if(last_reader)
+                {
+                    if(new_state.upgrade)
+                    {
+                        new_state.upgrade=false;
+                        new_state.exclusive=true;
+                    }
+                    else
+                    {
+                        if(new_state.exclusive_waiting)
+                        {
+                            --new_state.exclusive_waiting;
+                            new_state.exclusive_waiting_blocked=false;
+                        }
+                        new_state.shared_waiting=0;
+                    }
+                }
+                
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    if(last_reader)
+                    {
+                        if(old_state.upgrade)
+                        {
+                            bool const success=detail::win32::ReleaseSemaphore(upgrade_sem,1,NULL)!=0;
+                            BOOST_ASSERT(success);
+                        }
+                        else
+                        {
+                            release_waiters(old_state);
+                        }
+                    }
+                    break;
+                }
+                old_state=current_state;
+            }
+            while(true);
+        }
+
+        void lock()
+        {
+            bool const success=timed_lock(::boost::detail::get_system_time_sentinel());
+            BOOST_ASSERT(success);
+        }
+
+        bool timed_lock(boost::system_time const& wait_until)
+        {
+            while(true)
+            {
+                state_data old_state=state;
+
+                do
+                {
+                    state_data new_state=old_state;
+                    if(new_state.shared_count || new_state.exclusive)
+                    {
+                        ++new_state.exclusive_waiting;
+                        new_state.exclusive_waiting_blocked=true;
+                    }
+                    else
+                    {
+                        new_state.exclusive=true;
+                    }
+
+                    state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                    if(current_state==old_state)
+                    {
+                        break;
+                    }
+                    old_state=current_state;
+                }
+                while(true);
+
+                if(!old_state.shared_count && !old_state.exclusive)
+                {
+                    return true;
+                }
+                unsigned long const wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,true,::boost::detail::get_milliseconds_until(wait_until));
+                if(wait_res==detail::win32::timeout)
+                {
+                    do
+                    {
+                        state_data new_state=old_state;
+                        if(new_state.shared_count || new_state.exclusive)
+                        {
+                            if(new_state.exclusive_waiting)
+                            {
+                                --new_state.exclusive_waiting;
+                            }
+                        }
+                        else
+                        {
+                            new_state.exclusive=true;
+                        }
+
+                        state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                        if(current_state==old_state)
+                        {
+                            break;
+                        }
+                        old_state=current_state;
+                    }
+                    while(true);
+                    if(!old_state.shared_count && !old_state.exclusive)
+                    {
+                        return true;
+                    }
+                    return false;
+                }
+                BOOST_ASSERT(wait_res<2);
+            }
+        }
+
+        void unlock()
+        {
+            state_data old_state=state;
+            do
+            {
+                state_data new_state=old_state;
+                new_state.exclusive=false;
+                if(new_state.exclusive_waiting)
+                {
+                    --new_state.exclusive_waiting;
+                    new_state.exclusive_waiting_blocked=false;
+                }
+                new_state.shared_waiting=0;
+
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    break;
+                }
+                old_state=current_state;
+            }
+            while(true);
+            release_waiters(old_state);
+        }
+
+        void lock_upgrade()
+        {
+            while(true)
+            {
+                state_data old_state=state;
+                do
+                {
+                    state_data new_state=old_state;
+                    if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
+                    {
+                        ++new_state.shared_waiting;
+                    }
+                    else
+                    {
+                        ++new_state.shared_count;
+                        new_state.upgrade=true;
+                    }
+
+                    state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                    if(current_state==old_state)
+                    {
+                        break;
+                    }
+                    old_state=current_state;
+                }
+                while(true);
+
+                if(!(old_state.exclusive|| old_state.exclusive_waiting_blocked|| old_state.upgrade))
+                {
+                    return;
+                }
+                    
+                unsigned long const res=detail::win32::WaitForSingleObject(unlock_sem,detail::win32::infinite);
+                BOOST_ASSERT(res==0);
+            }
+        }
+
+        void unlock_upgrade()
+        {
+            state_data old_state=state;
+            do
+            {
+                state_data new_state=old_state;
+                new_state.upgrade=false;
+                bool const last_reader=!--new_state.shared_count;
+                
+                if(last_reader)
+                {
+                    if(new_state.exclusive_waiting)
+                    {
+                        --new_state.exclusive_waiting;
+                        new_state.exclusive_waiting_blocked=false;
+                    }
+                    new_state.shared_waiting=0;
+                }
+                
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    if(last_reader)
+                    {
+                        release_waiters(old_state);
+                    }
+                    break;
+                }
+                old_state=current_state;
+            }
+            while(true);
+        }
+
+        void unlock_upgrade_and_lock()
+        {
+            state_data old_state=state;
+            do
+            {
+                state_data new_state=old_state;
+                bool const last_reader=!--new_state.shared_count;
+                
+                if(last_reader)
+                {
+                    new_state.upgrade=false;
+                    new_state.exclusive=true;
+                }
+                
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    if(!last_reader)
+                    {
+                        unsigned long const res=detail::win32::WaitForSingleObject(upgrade_sem,detail::win32::infinite);
+                        BOOST_ASSERT(res==0);
+                    }
+                    break;
+                }
+                old_state=current_state;
+            }
+            while(true);
+        }
+
+        void unlock_and_lock_upgrade()
+        {
+            state_data old_state=state;
+            do
+            {
+                state_data new_state=old_state;
+                new_state.exclusive=false;
+                new_state.upgrade=true;
+                ++new_state.shared_count;
+                if(new_state.exclusive_waiting)
+                {
+                    --new_state.exclusive_waiting;
+                    new_state.exclusive_waiting_blocked=false;
+                }
+                new_state.shared_waiting=0;
+
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    break;
+                }
+                old_state=current_state;
+            }
+            while(true);
+            release_waiters(old_state);
+        }
+        
+        void unlock_and_lock_shared()
+        {
+            state_data old_state=state;
+            do
+            {
+                state_data new_state=old_state;
+                new_state.exclusive=false;
+                ++new_state.shared_count;
+                if(new_state.exclusive_waiting)
+                {
+                    --new_state.exclusive_waiting;
+                    new_state.exclusive_waiting_blocked=false;
+                }
+                new_state.shared_waiting=0;
+
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    break;
+                }
+                old_state=current_state;
+            }
+            while(true);
+            release_waiters(old_state);
+        }
+        
+        void unlock_upgrade_and_lock_shared()
+        {
+            state_data old_state=state;
+            do
+            {
+                state_data new_state=old_state;
+                new_state.upgrade=false;
+                if(new_state.exclusive_waiting)
+                {
+                    --new_state.exclusive_waiting;
+                    new_state.exclusive_waiting_blocked=false;
+                }
+                new_state.shared_waiting=0;
+
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    break;
+                }
+                old_state=current_state;
+            }
+            while(true);
+            release_waiters(old_state);
+        }
+        
+    };
+}
+
+
+#endif
Modified: trunk/boost/thread/win32/thread_primitives.hpp
==============================================================================
--- trunk/boost/thread/win32/thread_primitives.hpp	(original)
+++ trunk/boost/thread/win32/thread_primitives.hpp	2007-10-10 11:33:49 EDT (Wed, 10 Oct 2007)
@@ -112,7 +112,7 @@
             
             inline handle create_anonymous_event(event_type type,initial_event_state state)
             {
-                handle const res=CreateEventA(0,type,state,0);
+                handle const res=win32::CreateEventA(0,type,state,0);
                 if(!res)
                 {
                     throw thread_resource_error();
@@ -177,6 +177,7 @@
                 {
                     cleanup();
                     handle_to_manage=new_handle;
+                    return *this;
                 }
 
                 operator handle() const
Modified: trunk/boost/thread/xtime.hpp
==============================================================================
--- trunk/boost/thread/xtime.hpp	(original)
+++ trunk/boost/thread/xtime.hpp	2007-10-10 11:33:49 EDT (Wed, 10 Oct 2007)
@@ -10,6 +10,8 @@
 #include <boost/thread/detail/config.hpp>
 
 #include <boost/cstdint.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/date_time/posix_time/conversion.hpp>
 
 namespace boost {
 
@@ -49,6 +51,16 @@
         return (xt1.sec > xt2.sec) ? 1 : -1;
 }
 
+inline xtime get_xtime(boost::system_time const& abs_time)
+{
+    xtime res={0};
+    boost::posix_time::time_duration const time_since_epoch=abs_time-boost::posix_time::from_time_t(0);
+            
+    res.sec=time_since_epoch.total_seconds();
+    res.nsec=time_since_epoch.fractional_seconds()*(1000000000/time_since_epoch.ticks_per_second());
+    return res;
+}
+
 } // namespace boost
 
 #endif //BOOST_XTIME_WEK070601_HPP
Deleted: trunk/libs/thread/src/mutex.cpp
==============================================================================
--- trunk/libs/thread/src/mutex.cpp	2007-10-10 11:33:49 EDT (Wed, 10 Oct 2007)
+++ (empty file)
@@ -1,561 +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/mutex.hpp>
-#include <boost/thread/xtime.hpp>
-#include <boost/thread/thread.hpp>
-#include <boost/thread/exceptions.hpp>
-#include <boost/limits.hpp>
-#include <string>
-#include <stdexcept>
-#include <cassert>
-#include "timeconv.inl"
-
-#if defined(BOOST_HAS_WINTHREADS)
-#   include <new>
-#   include <boost/thread/once.hpp>
-#   include <windows.h>
-#   include <time.h>
-#   include "mutex.inl"
-#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
-
-namespace boost {
-
-#if defined(BOOST_HAS_WINTHREADS)
-
-mutex::mutex()
-    : m_mutex(0)
-    , m_critical_section(false)
-{
-    m_critical_section = true;
-    if (m_critical_section)
-        m_mutex = new_critical_section();
-    else
-        m_mutex = new_mutex(0);
-}
-
-mutex::~mutex()
-{
-    if (m_critical_section)
-        delete_critical_section(m_mutex);
-    else
-        delete_mutex(m_mutex);
-}
-
-void mutex::do_lock()
-{
-    if (m_critical_section)
-        wait_critical_section_infinite(m_mutex);
-    else
-        wait_mutex(m_mutex, INFINITE);
-}
-
-void mutex::do_unlock()
-{
-    if (m_critical_section)
-        release_critical_section(m_mutex);
-    else
-        release_mutex(m_mutex);
-}
-
-void mutex::do_lock(cv_state&)
-{
-    do_lock();
-}
-
-void mutex::do_unlock(cv_state&)
-{
-    do_unlock();
-}
-
-try_mutex::try_mutex()
-    : m_mutex(0)
-    , m_critical_section(false)
-{
-    m_critical_section = has_TryEnterCriticalSection();
-    if (m_critical_section)
-        m_mutex = new_critical_section();
-    else
-        m_mutex = new_mutex(0);
-}
-
-try_mutex::~try_mutex()
-{
-    if (m_critical_section)
-        delete_critical_section(m_mutex);
-    else
-        delete_mutex(m_mutex);
-}
-
-void try_mutex::do_lock()
-{
-    if (m_critical_section)
-        wait_critical_section_infinite(m_mutex);
-    else
-        wait_mutex(m_mutex, INFINITE);
-}
-
-bool try_mutex::do_trylock()
-{
-    if (m_critical_section)
-        return wait_critical_section_try(m_mutex);
-    else
-        return wait_mutex(m_mutex, 0) == WAIT_OBJECT_0;
-}
-
-void try_mutex::do_unlock()
-{
-    if (m_critical_section)
-        release_critical_section(m_mutex);
-    else
-        release_mutex(m_mutex);
-}
-
-void try_mutex::do_lock(cv_state&)
-{
-    do_lock();
-}
-
-void try_mutex::do_unlock(cv_state&)
-{
-    do_unlock();
-}
-
-timed_mutex::timed_mutex()
-    : m_mutex(0)
-{
-    m_mutex = new_mutex(0);
-}
-
-timed_mutex::~timed_mutex()
-{
-    delete_mutex(m_mutex);
-}
-
-void timed_mutex::do_lock()
-{
-    wait_mutex(m_mutex, INFINITE);
-}
-
-bool timed_mutex::do_trylock()
-{
-    return wait_mutex(m_mutex, 0) == WAIT_OBJECT_0;
-}
-
-bool timed_mutex::do_timedlock(const xtime& xt)
-{
-    for (;;)
-    {
-        int milliseconds;
-        to_duration(xt, milliseconds);
-
-        int res = wait_mutex(m_mutex, milliseconds);
-
-        if (res == WAIT_TIMEOUT)
-        {
-            boost::xtime cur;
-            boost::xtime_get(&cur, boost::TIME_UTC);
-            if (boost::xtime_cmp(xt, cur) > 0)
-                continue;
-        }
-
-        return res == WAIT_OBJECT_0;
-    }
-}
-
-void timed_mutex::do_unlock()
-{
-    release_mutex(m_mutex);
-}
-
-void timed_mutex::do_lock(cv_state&)
-{
-    do_lock();
-}
-
-void timed_mutex::do_unlock(cv_state&)
-{
-    do_unlock();
-}
-
-#elif defined(BOOST_HAS_PTHREADS)
-
-mutex::mutex()
-{
-    int res = 0;
-    res = pthread_mutex_init(&m_mutex, 0);
-    if (res != 0)
-        throw thread_resource_error();
-}
-
-mutex::~mutex()
-{
-    int res = 0;
-    res = pthread_mutex_destroy(&m_mutex);
-    assert(res == 0);
-}
-
-void mutex::do_lock()
-{
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    if (res == EDEADLK) throw lock_error();
-    assert(res == 0);
-}
-
-void mutex::do_unlock()
-{
-    int res = 0;
-    res = pthread_mutex_unlock(&m_mutex);
-    if (res == EPERM) throw lock_error();
-    assert(res == 0);
-}
-
-void mutex::do_lock(cv_state&)
-{
-}
-
-void mutex::do_unlock(cv_state& state)
-{
-    state.pmutex = &m_mutex;
-}
-
-try_mutex::try_mutex()
-{
-    int res = 0;
-    res = pthread_mutex_init(&m_mutex, 0);
-    if (res != 0)
-        throw thread_resource_error();
-}
-
-try_mutex::~try_mutex()
-{
-    int res = 0;
-    res = pthread_mutex_destroy(&m_mutex);
-    assert(res == 0);
-}
-
-void try_mutex::do_lock()
-{
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    if (res == EDEADLK) throw lock_error();
-    assert(res == 0);
-}
-
-bool try_mutex::do_trylock()
-{
-    int res = 0;
-    res = pthread_mutex_trylock(&m_mutex);
-    if (res == EDEADLK) throw lock_error();
-    assert(res == 0 || res == EBUSY);
-    return res == 0;
-}
-
-void try_mutex::do_unlock()
-{
-    int res = 0;
-    res = pthread_mutex_unlock(&m_mutex);
-    if (res == EPERM) throw lock_error();
-    assert(res == 0);
-}
-
-void try_mutex::do_lock(cv_state&)
-{
-}
-
-void try_mutex::do_unlock(cv_state& state)
-{
-    state.pmutex = &m_mutex;
-}
-
-timed_mutex::timed_mutex()
-    : m_locked(false)
-{
-    int res = 0;
-    res = pthread_mutex_init(&m_mutex, 0);
-    if (res != 0)
-        throw thread_resource_error();
-
-    res = pthread_cond_init(&m_condition, 0);
-    if (res != 0)
-    {
-        pthread_mutex_destroy(&m_mutex);
-        throw thread_resource_error();
-    }
-}
-
-timed_mutex::~timed_mutex()
-{
-    assert(!m_locked);
-    int res = 0;
-    res = pthread_mutex_destroy(&m_mutex);
-    assert(res == 0);
-
-    res = pthread_cond_destroy(&m_condition);
-    assert(res == 0);
-}
-
-void timed_mutex::do_lock()
-{
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-
-    while (m_locked)
-    {
-        res = pthread_cond_wait(&m_condition, &m_mutex);
-        assert(res == 0);
-    }
-
-    assert(!m_locked);
-    m_locked = true;
-
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-}
-
-bool timed_mutex::do_trylock()
-{
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-
-    bool ret = false;
-    if (!m_locked)
-    {
-        m_locked = true;
-        ret = true;
-    }
-
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-    return ret;
-}
-
-bool timed_mutex::do_timedlock(const xtime& xt)
-{
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-
-    timespec ts;
-    to_timespec(xt, ts);
-
-    while (m_locked)
-    {
-        res = pthread_cond_timedwait(&m_condition, &m_mutex, &ts);
-        assert(res == 0 || res == ETIMEDOUT);
-
-        if (res == ETIMEDOUT)
-            break;
-    }
-
-    bool ret = false;
-    if (!m_locked)
-    {
-        m_locked = true;
-        ret = true;
-    }
-
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-    return ret;
-}
-
-void timed_mutex::do_unlock()
-{
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-
-    assert(m_locked);
-    m_locked = false;
-
-    res = pthread_cond_signal(&m_condition);
-    assert(res == 0);
-
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-}
-
-void timed_mutex::do_lock(cv_state&)
-{
-    int res = 0;
-    while (m_locked)
-    {
-        res = pthread_cond_wait(&m_condition, &m_mutex);
-        assert(res == 0);
-    }
-
-    assert(!m_locked);
-    m_locked = true;
-
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-}
-
-void timed_mutex::do_unlock(cv_state& state)
-{
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-
-    assert(m_locked);
-    m_locked = false;
-
-    res = pthread_cond_signal(&m_condition);
-    assert(res == 0);
-
-    state.pmutex = &m_mutex;
-}
-
-#elif defined(BOOST_HAS_MPTASKS)
-
-using threads::mac::detail::safe_enter_critical_region;
-
-mutex::mutex()
-{
-}
-
-mutex::~mutex()
-{
-}
-
-void mutex::do_lock()
-{
-    OSStatus lStatus = noErr;
-    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
-        m_mutex_mutex);
-    assert(lStatus == noErr);
-}
-
-void mutex::do_unlock()
-{
-    OSStatus lStatus = noErr;
-    lStatus = MPExitCriticalRegion(m_mutex);
-    assert(lStatus == noErr);
-}
-
-void mutex::do_lock(cv_state& /*state*/)
-{
-    do_lock();
-}
-
-void mutex::do_unlock(cv_state& /*state*/)
-{
-    do_unlock();
-}
-
-try_mutex::try_mutex()
-{
-}
-
-try_mutex::~try_mutex()
-{
-}
-
-void try_mutex::do_lock()
-{
-    OSStatus lStatus = noErr;
-    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
-        m_mutex_mutex);
-    assert(lStatus == noErr);
-}
-
-bool try_mutex::do_trylock()
-{
-    OSStatus lStatus = noErr;
-    lStatus = MPEnterCriticalRegion(m_mutex, kDurationImmediate);
-    assert(lStatus == noErr || lStatus == kMPTimeoutErr);
-    return lStatus == noErr;
-}
-
-void try_mutex::do_unlock()
-{
-    OSStatus lStatus = noErr;
-    lStatus = MPExitCriticalRegion(m_mutex);
-    assert(lStatus == noErr);
-}
-
-void try_mutex::do_lock(cv_state& /*state*/)
-{
-    do_lock();
-}
-
-void try_mutex::do_unlock(cv_state& /*state*/)
-{
-    do_unlock();
-}
-
-timed_mutex::timed_mutex()
-{
-}
-
-timed_mutex::~timed_mutex()
-{
-}
-
-void timed_mutex::do_lock()
-{
-    OSStatus lStatus = noErr;
-    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
-        m_mutex_mutex);
-    assert(lStatus == noErr);
-}
-
-bool timed_mutex::do_trylock()
-{
-    OSStatus lStatus = noErr;
-    lStatus = MPEnterCriticalRegion(m_mutex, kDurationImmediate);
-    assert(lStatus == noErr || lStatus == kMPTimeoutErr);
-    return(lStatus == noErr);
-}
-
-bool timed_mutex::do_timedlock(const xtime& xt)
-{
-    int microseconds;
-    to_microduration(xt, microseconds);
-    Duration lDuration = kDurationMicrosecond * microseconds;
-
-    OSStatus lStatus = noErr;
-    lStatus = safe_enter_critical_region(m_mutex, lDuration, m_mutex_mutex);
-    assert(lStatus == noErr || lStatus == kMPTimeoutErr);
-
-    return(lStatus == noErr);
-}
-
-void timed_mutex::do_unlock()
-{
-    OSStatus lStatus = noErr;
-    lStatus = MPExitCriticalRegion(m_mutex);
-    assert(lStatus == noErr);
-}
-
-void timed_mutex::do_lock(cv_state& /*state*/)
-{
-    do_lock();
-}
-
-void timed_mutex::do_unlock(cv_state& /*state*/)
-{
-    do_unlock();
-}
-
-#endif
-
-} // namespace boost
-
-// Change Log:
-//   8 Feb 01  WEKEMPF Initial version.
Deleted: trunk/libs/thread/src/mutex.inl
==============================================================================
--- trunk/libs/thread/src/mutex.inl	2007-10-10 11:33:49 EDT (Wed, 10 Oct 2007)
+++ (empty file)
@@ -1,132 +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)
-// boostinspect:nounnamed
-
-namespace {
-
-#if defined(BOOST_HAS_WINTHREADS)
-//:PREVENT THIS FROM BEING DUPLICATED
-typedef BOOL (WINAPI* TryEnterCriticalSection_type)(LPCRITICAL_SECTION lpCriticalSection);
-TryEnterCriticalSection_type g_TryEnterCriticalSection = 0;
-boost::once_flag once_init_TryEnterCriticalSection = BOOST_ONCE_INIT;
-
-void init_TryEnterCriticalSection()
-{
-    //TryEnterCriticalSection is only available on WinNT 4.0 or later; 
-    //it is not available on Win9x.
-
-    OSVERSIONINFO version_info = {sizeof(OSVERSIONINFO)};
-    ::GetVersionEx(&version_info);
-    if (version_info.dwPlatformId == VER_PLATFORM_WIN32_NT && 
-        version_info.dwMajorVersion >= 4)
-    {
-        if (HMODULE kernel_module = GetModuleHandle(TEXT("KERNEL32.DLL")))
-        {
-            g_TryEnterCriticalSection = reinterpret_cast<TryEnterCriticalSection_type>(
-#if defined(BOOST_NO_ANSI_APIS)
-                GetProcAddressW(kernel_module, L"TryEnterCriticalSection")
-#else
-                GetProcAddress(kernel_module, "TryEnterCriticalSection")
-#endif        
-                );
-        }
-    }
-}
-
-inline bool has_TryEnterCriticalSection()
-{
-    boost::call_once(once_init_TryEnterCriticalSection, init_TryEnterCriticalSection);
-    return g_TryEnterCriticalSection != 0;
-}
-
-inline HANDLE mutex_cast(void* p)
-{
-    return reinterpret_cast<HANDLE>(p);
-}
-
-inline LPCRITICAL_SECTION critical_section_cast(void* p)
-{
-    return reinterpret_cast<LPCRITICAL_SECTION>(p);
-}
-
-inline void* new_critical_section()
-{
-    try
-    {
-        LPCRITICAL_SECTION critical_section = new CRITICAL_SECTION;
-        if (critical_section == 0) throw boost::thread_resource_error();
-        InitializeCriticalSection(critical_section);
-        return critical_section;
-    }
-    catch(...)
-    {
-        throw boost::thread_resource_error();
-    }
-}
-
-inline void* new_mutex(const char* name)
-{
-#if defined(BOOST_NO_ANSI_APIS)
-    int const num_wide_chars = ::MultiByteToWideChar(CP_ACP, 0, name, -1, 0, 0);
-    LPWSTR const wide_name = (LPWSTR)_alloca( (num_wide_chars+1) * 2 );
-    int const res=::MultiByteToWideChar(CP_ACP, 0, name, -1, wide_name, num_wide_chars);
-    if(!res)
-        throw boost::thread_resource_error();
-    HANDLE mutex = CreateMutexW(0, 0, wide_name);
-#else
-    HANDLE mutex = CreateMutexA(0, 0, name);
-#endif
-    if (mutex == 0 || mutex == INVALID_HANDLE_VALUE) //:xxx (check for both values?)
-        throw boost::thread_resource_error();
-    return reinterpret_cast<void*>(mutex);
-}
-
-inline void delete_critical_section(void* mutex)
-{
-    DeleteCriticalSection(critical_section_cast(mutex));
-    delete critical_section_cast(mutex);
-}
-
-inline void delete_mutex(void* mutex)
-{
-    int res = 0;
-    res = CloseHandle(mutex_cast(mutex));
-    assert(res);
-}
-
-inline void wait_critical_section_infinite(void* mutex)
-{
-    EnterCriticalSection(critical_section_cast(mutex)); //:xxx Can throw an exception under low memory conditions
-}
-
-inline bool wait_critical_section_try(void* mutex)
-{
-    BOOL res = g_TryEnterCriticalSection(critical_section_cast(mutex));
-    return res != 0;
-}
-
-inline int wait_mutex(void* mutex, int time)
-{
-    unsigned int res = 0;
-    res = WaitForSingleObject(mutex_cast(mutex), time);
-//:xxx    assert(res != WAIT_FAILED && res != WAIT_ABANDONED);
-    return res;
-}
-
-inline void release_critical_section(void* mutex)
-{
-    LeaveCriticalSection(critical_section_cast(mutex));
-}
-
-inline void release_mutex(void* mutex)
-{
-    BOOL res = FALSE;
-    res = ReleaseMutex(mutex_cast(mutex));
-    assert(res);
-}
-#endif
-
-}
Deleted: trunk/libs/thread/src/once.cpp
==============================================================================
--- trunk/libs/thread/src/once.cpp	2007-10-10 11:33:49 EDT (Wed, 10 Oct 2007)
+++ (empty file)
@@ -1,50 +0,0 @@
-// 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)
-
-#include <boost/thread/detail/config.hpp>
-#ifdef BOOST_HAS_MPTASKS
-
-#include <boost/detail/workaround.hpp>
-
-#include <boost/thread/once.hpp>
-#include <cstdio>
-#include <cassert>
-
-#include <Multiprocessing.h>
-
-namespace {
-void *remote_call_proxy(void *pData)
-{
-    std::pair<void (*)(), boost::once_flag *> &rData(
-        *reinterpret_cast<std::pair<void (*)(), boost::once_flag *> *>(pData));
-
-    if(*rData.second == false)
-    {
-        rData.first();
-        *rData.second = true;
-    }
-
-    return(NULL);
-}
-}
-
-namespace boost {
-
-    void call_once(once_flag& flag, void (*func)())
-{
-    if(flag == false)
-    {
-        // all we do here is make a remote call to blue, as blue is not
-        // reentrant.
-        std::pair<void (*)(), once_flag *> sData(func, &flag);
-        MPRemoteCall(remote_call_proxy, &sData, kMPOwningProcessRemoteContext);
-        assert(flag == true);
-    }
-}
-
-}
-#endif
Deleted: trunk/libs/thread/src/recursive_mutex.cpp
==============================================================================
--- trunk/libs/thread/src/recursive_mutex.cpp	2007-10-10 11:33:49 EDT (Wed, 10 Oct 2007)
+++ (empty file)
@@ -1,1040 +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/recursive_mutex.hpp>
-#include <boost/thread/xtime.hpp>
-#include <boost/thread/thread.hpp>
-#include <boost/limits.hpp>
-#include <string>
-#include <stdexcept>
-#include <cassert>
-#include "timeconv.inl"
-
-#if defined(BOOST_HAS_WINTHREADS)
-#   include <new>
-#   include <boost/thread/once.hpp>
-#   include <windows.h>
-#   include <time.h>
-#   include "mutex.inl"
-#elif defined(BOOST_HAS_PTHREADS)
-#   include <errno.h>
-#elif defined(BOOST_HAS_MPTASKS)
-#   include <MacErrors.h>
-#   include "safe.hpp"
-#endif
-
-namespace boost {
-
-#if defined(BOOST_HAS_WINTHREADS)
-
-recursive_mutex::recursive_mutex()
-    : m_mutex(0)
-    , m_critical_section(false)
-    , m_count(0)
-{
-    m_critical_section = true;
-    if (m_critical_section)
-        m_mutex = new_critical_section();
-    else
-        m_mutex = new_mutex(0);
-}
-
-recursive_mutex::~recursive_mutex()
-{
-    if (m_critical_section)
-        delete_critical_section(m_mutex);
-    else
-        delete_mutex(m_mutex);
-}
-
-void recursive_mutex::do_lock()
-{
-    if (m_critical_section)
-        wait_critical_section_infinite(m_mutex);
-    else
-        wait_mutex(m_mutex, INFINITE);
-
-    if (++m_count > 1)
-    {
-        if (m_critical_section)
-            release_critical_section(m_mutex);
-        else
-            release_mutex(m_mutex);
-    }
-}
-
-void recursive_mutex::do_unlock()
-{
-    if (--m_count == 0)
-    {
-        if (m_critical_section)
-            release_critical_section(m_mutex);
-        else
-            release_mutex(m_mutex);
-    }
-}
-
-void recursive_mutex::do_lock(cv_state& state)
-{
-    if (m_critical_section)
-        wait_critical_section_infinite(m_mutex);
-    else
-        wait_mutex(m_mutex, INFINITE);
-
-    m_count = state;
-}
-
-void recursive_mutex::do_unlock(cv_state& state)
-{
-    state = m_count;
-    m_count = 0;
-
-    if (m_critical_section)
-        release_critical_section(m_mutex);
-    else
-        release_mutex(m_mutex);
-}
-
-recursive_try_mutex::recursive_try_mutex()
-    : m_mutex(0)
-    , m_critical_section(false)
-    , m_count(0)
-{
-    m_critical_section = has_TryEnterCriticalSection();
-    if (m_critical_section)
-        m_mutex = new_critical_section();
-    else
-        m_mutex = new_mutex(0);
-}
-
-recursive_try_mutex::~recursive_try_mutex()
-{
-    if (m_critical_section)
-        delete_critical_section(m_mutex);
-    else
-        delete_mutex(m_mutex);
-}
-
-void recursive_try_mutex::do_lock()
-{
-    if (m_critical_section)
-        wait_critical_section_infinite(m_mutex);
-    else
-        wait_mutex(m_mutex, INFINITE);
-
-    if (++m_count > 1)
-    {
-        if (m_critical_section)
-            release_critical_section(m_mutex);
-        else
-            release_mutex(m_mutex);
-    }
-}
-
-bool recursive_try_mutex::do_trylock()
-{
-    bool res = false;
-    if (m_critical_section)
-        res = wait_critical_section_try(m_mutex);
-    else
-        res = wait_mutex(m_mutex, 0) == WAIT_OBJECT_0;
-
-    if (res)
-    {
-        if (++m_count > 1)
-        {
-            if (m_critical_section)
-                release_critical_section(m_mutex);
-            else
-                release_mutex(m_mutex);
-        }
-        return true;
-    }
-    return false;
-}
-
-void recursive_try_mutex::do_unlock()
-{
-    if (--m_count == 0)
-    {
-        if (m_critical_section)
-            release_critical_section(m_mutex);
-        else
-            release_mutex(m_mutex);
-    }
-}
-
-void recursive_try_mutex::do_lock(cv_state& state)
-{
-    if (m_critical_section)
-        wait_critical_section_infinite(m_mutex);
-    else
-        wait_mutex(m_mutex, INFINITE);
-
-    m_count = state;
-}
-
-void recursive_try_mutex::do_unlock(cv_state& state)
-{
-    state = m_count;
-    m_count = 0;
-
-    if (m_critical_section)
-        release_critical_section(m_mutex);
-    else
-        release_mutex(m_mutex);
-}
-
-recursive_timed_mutex::recursive_timed_mutex()
-    : m_mutex(0)
-    , m_count(0)
-{
-    m_mutex = new_mutex(0);
-}
-
-recursive_timed_mutex::~recursive_timed_mutex()
-{
-    delete_mutex(m_mutex);
-}
-
-void recursive_timed_mutex::do_lock()
-{
-    wait_mutex(m_mutex, INFINITE);
-
-    if (++m_count > 1)
-        release_mutex(m_mutex);
-}
-
-bool recursive_timed_mutex::do_trylock()
-{
-    bool res = wait_mutex(m_mutex, 0) == WAIT_OBJECT_0;
-
-    if (res)
-    {
-        if (++m_count > 1)
-            release_mutex(m_mutex);
-        return true;
-    }
-    return false;
-}
-
-bool recursive_timed_mutex::do_timedlock(const xtime& xt)
-{
-    for (;;)
-    {
-        int milliseconds;
-        to_duration(xt, milliseconds);
-
-        unsigned int res = wait_mutex(m_mutex, milliseconds);
-
-        if (res == WAIT_TIMEOUT)
-        {
-            xtime cur;
-            xtime_get(&cur, TIME_UTC);
-            if (xtime_cmp(xt, cur) > 0)
-                continue;
-        }
-
-        if (res == WAIT_OBJECT_0)
-        {
-            if (++m_count > 1)
-                release_mutex(m_mutex);
-            return true;
-        }
-
-        return false;
-    }
-}
-
-void recursive_timed_mutex::do_unlock()
-{
-    if (--m_count == 0)
-        release_mutex(m_mutex);
-}
-
-void recursive_timed_mutex::do_lock(cv_state& state)
-{
-    wait_mutex(m_mutex, INFINITE);
-
-    m_count = state;
-}
-
-void recursive_timed_mutex::do_unlock(cv_state& state)
-{
-    state = m_count;
-    m_count = 0;
-
-    release_mutex(m_mutex);
-}
-
-#elif defined(BOOST_HAS_PTHREADS)
-
-recursive_mutex::recursive_mutex()
-    : m_count(0)
-#   if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-    , m_valid_id(false)
-#   endif
-{
-    pthread_mutexattr_t attr;
-    int res = pthread_mutexattr_init(&attr);
-    assert(res == 0);
-
-#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-    res = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-    assert(res == 0);
-#   endif
-
-    res = pthread_mutex_init(&m_mutex, &attr);
-    {
-        int res = 0;
-        res = pthread_mutexattr_destroy(&attr);
-        assert(res == 0);
-    }
-    if (res != 0)
-        throw thread_resource_error();
-
-#   if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-    res = pthread_cond_init(&m_unlocked, 0);
-    if (res != 0)
-    {
-        pthread_mutex_destroy(&m_mutex);
-        throw thread_resource_error();
-    }
-#   endif
-}
-
-recursive_mutex::~recursive_mutex()
-{
-    int res = 0;
-    res = pthread_mutex_destroy(&m_mutex);
-    assert(res == 0);
-
-#   if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-    res = pthread_cond_destroy(&m_unlocked);
-    assert(res == 0);
-#   endif
-}
-
-void recursive_mutex::do_lock()
-{
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-
-#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-    if (++m_count > 1)
-    {
-        res = pthread_mutex_unlock(&m_mutex);
-        assert(res == 0);
-    }
-#   else
-    pthread_t tid = pthread_self();
-    if (m_valid_id && pthread_equal(m_thread_id, tid))
-        ++m_count;
-    else
-    {
-        while (m_valid_id)
-        {
-            res = pthread_cond_wait(&m_unlocked, &m_mutex);
-            assert(res == 0);
-        }
-
-        m_thread_id = tid;
-        m_valid_id = true;
-        m_count = 1;
-    }
-
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-#   endif
-}
-
-void recursive_mutex::do_unlock()
-{
-#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-    if (--m_count == 0)
-    {
-        int res = 0;
-        res = pthread_mutex_unlock(&m_mutex);
-        assert(res == 0);
-    }
-#   else
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-
-    pthread_t tid = pthread_self();
-    if (m_valid_id && !pthread_equal(m_thread_id, tid))
-    {
-        res = pthread_mutex_unlock(&m_mutex);
-        assert(res == 0);
-        throw lock_error();
-    }
-
-    if (--m_count == 0)
-    {
-        assert(m_valid_id);
-        m_valid_id = false;
-
-        res = pthread_cond_signal(&m_unlocked);
-        assert(res == 0);
-    }
-
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-#   endif
-}
-
-void recursive_mutex::do_lock(cv_state& state)
-{
-#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-    m_count = state.count;
-#   else
-    int res = 0;
-
-    while (m_valid_id)
-    {
-        res = pthread_cond_wait(&m_unlocked, &m_mutex);
-        assert(res == 0);
-    }
-
-    m_thread_id = pthread_self();
-    m_valid_id = true;
-    m_count = state.count;
-
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-#   endif
-}
-
-void recursive_mutex::do_unlock(cv_state& state)
-{
-#   if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-
-    assert(m_valid_id);
-    m_valid_id = false;
-
-    res = pthread_cond_signal(&m_unlocked);
-    assert(res == 0);
-#   endif
-
-    state.pmutex = &m_mutex;
-    state.count = m_count;
-    m_count = 0;
-}
-
-recursive_try_mutex::recursive_try_mutex()
-    : m_count(0)
-#   if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-    , m_valid_id(false)
-#   endif
-{
-    pthread_mutexattr_t attr;
-    int res = pthread_mutexattr_init(&attr);
-    assert(res == 0);
-
-#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-    res = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-    assert(res == 0);
-#   endif
-
-    res = pthread_mutex_init(&m_mutex, &attr);
-    {
-        int res = 0;
-        res = pthread_mutexattr_destroy(&attr);
-        assert(res == 0);
-    }
-    if (res != 0)
-        throw thread_resource_error();
-
-#   if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-    res = pthread_cond_init(&m_unlocked, 0);
-    if (res != 0)
-    {
-        pthread_mutex_destroy(&m_mutex);
-        throw thread_resource_error();
-    }
-#   endif
-}
-
-recursive_try_mutex::~recursive_try_mutex()
-{
-    int res = 0;
-    res = pthread_mutex_destroy(&m_mutex);
-    assert(res == 0);
-
-#   if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-    res = pthread_cond_destroy(&m_unlocked);
-    assert(res == 0);
-#   endif
-}
-
-void recursive_try_mutex::do_lock()
-{
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-
-#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-    if (++m_count > 1)
-    {
-        res = pthread_mutex_unlock(&m_mutex);
-        assert(res == 0);
-    }
-#   else
-    pthread_t tid = pthread_self();
-    if (m_valid_id && pthread_equal(m_thread_id, tid))
-        ++m_count;
-    else
-    {
-        while (m_valid_id)
-        {
-            res = pthread_cond_wait(&m_unlocked, &m_mutex);
-            assert(res == 0);
-        }
-
-        m_thread_id = tid;
-        m_valid_id = true;
-        m_count = 1;
-    }
-
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-#   endif
-}
-
-bool recursive_try_mutex::do_trylock()
-{
-#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-    int res = 0;
-    res = pthread_mutex_trylock(&m_mutex);
-    assert(res == 0 || res == EBUSY);
-
-    if (res == 0)
-    {
-        if (++m_count > 1)
-        {
-            res = pthread_mutex_unlock(&m_mutex);
-            assert(res == 0);
-        }
-        return true;
-    }
-
-    return false;
-#   else
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-
-    bool ret = false;
-    pthread_t tid = pthread_self();
-    if (m_valid_id && pthread_equal(m_thread_id, tid))
-    {
-        ++m_count;
-        ret = true;
-    }
-    else if (!m_valid_id)
-    {
-        m_thread_id = tid;
-        m_valid_id = true;
-        m_count = 1;
-        ret = true;
-    }
-
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-    return ret;
-#   endif
-}
-
-void recursive_try_mutex::do_unlock()
-{
-#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-    if (--m_count == 0)
-    {
-        int res = 0;
-        res = pthread_mutex_unlock(&m_mutex);
-        assert(res == 0);
-    }
-#   else
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-
-    pthread_t tid = pthread_self();
-    if (m_valid_id && !pthread_equal(m_thread_id, tid))
-    {
-        res = pthread_mutex_unlock(&m_mutex);
-        assert(res == 0);
-        throw lock_error();
-    }
-
-    if (--m_count == 0)
-    {
-        assert(m_valid_id);
-        m_valid_id = false;
-
-        res = pthread_cond_signal(&m_unlocked);
-        assert(res == 0);
-    }
-
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-#   endif
-}
-
-void recursive_try_mutex::do_lock(cv_state& state)
-{
-#   if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-    m_count = state.count;
-#   else
-    int res = 0;
-
-    while (m_valid_id)
-    {
-        res = pthread_cond_wait(&m_unlocked, &m_mutex);
-        assert(res == 0);
-    }
-
-    m_thread_id = pthread_self();
-    m_valid_id = true;
-    m_count = state.count;
-
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-#   endif
-}
-
-void recursive_try_mutex::do_unlock(cv_state& state)
-{
-#   if !defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE)
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-
-    assert(m_valid_id);
-    m_valid_id = false;
-
-    res = pthread_cond_signal(&m_unlocked);
-    assert(res == 0);
-#   endif
-
-    state.pmutex = &m_mutex;
-    state.count = m_count;
-    m_count = 0;
-}
-
-recursive_timed_mutex::recursive_timed_mutex()
-    : m_valid_id(false), m_count(0)
-{
-    int res = 0;
-    res = pthread_mutex_init(&m_mutex, 0);
-    if (res != 0)
-        throw thread_resource_error();
-
-    res = pthread_cond_init(&m_unlocked, 0);
-    if (res != 0)
-    {
-        pthread_mutex_destroy(&m_mutex);
-        throw thread_resource_error();
-    }
-}
-
-recursive_timed_mutex::~recursive_timed_mutex()
-{
-    int res = 0;
-    res = pthread_mutex_destroy(&m_mutex);
-    assert(res == 0);
-
-    res = pthread_cond_destroy(&m_unlocked);
-    assert(res == 0);
-}
-
-void recursive_timed_mutex::do_lock()
-{
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-
-    pthread_t tid = pthread_self();
-    if (m_valid_id && pthread_equal(m_thread_id, tid))
-        ++m_count;
-    else
-    {
-        while (m_valid_id)
-        {
-            res = pthread_cond_wait(&m_unlocked, &m_mutex);
-            assert(res == 0);
-        }
-
-        m_thread_id = tid;
-        m_valid_id = true;
-        m_count = 1;
-    }
-
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-}
-
-bool recursive_timed_mutex::do_trylock()
-{
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-
-    bool ret = false;
-    pthread_t tid = pthread_self();
-    if (m_valid_id && pthread_equal(m_thread_id, tid))
-    {
-        ++m_count;
-        ret = true;
-    }
-    else if (!m_valid_id)
-    {
-        m_thread_id = tid;
-        m_valid_id = true;
-        m_count = 1;
-        ret = true;
-    }
-
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-    return ret;
-}
-
-bool recursive_timed_mutex::do_timedlock(const xtime& xt)
-{
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-
-    bool ret = false;
-    pthread_t tid = pthread_self();
-    if (m_valid_id && pthread_equal(m_thread_id, tid))
-    {
-        ++m_count;
-        ret = true;
-    }
-    else
-    {
-        timespec ts;
-        to_timespec(xt, ts);
-
-        while (m_valid_id)
-        {
-            res = pthread_cond_timedwait(&m_unlocked, &m_mutex, &ts);
-            if (res == ETIMEDOUT)
-                break;
-            assert(res == 0);
-        }
-
-        if (!m_valid_id)
-        {
-            m_thread_id = tid;
-            m_valid_id = true;
-            m_count = 1;
-            ret = true;
-        }
-    }
-
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-    return ret;
-}
-
-void recursive_timed_mutex::do_unlock()
-{
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-
-    pthread_t tid = pthread_self();
-    if (m_valid_id && !pthread_equal(m_thread_id, tid))
-    {
-        res = pthread_mutex_unlock(&m_mutex);
-        assert(res == 0);
-        throw lock_error();
-    }
-
-    if (--m_count == 0)
-    {
-        assert(m_valid_id);
-        m_valid_id = false;
-
-        res = pthread_cond_signal(&m_unlocked);
-        assert(res == 0);
-    }
-
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-}
-
-void recursive_timed_mutex::do_lock(cv_state& state)
-{
-    int res = 0;
-
-    while (m_valid_id)
-    {
-        res = pthread_cond_wait(&m_unlocked, &m_mutex);
-        assert(res == 0);
-    }
-
-    m_thread_id = pthread_self();
-    m_valid_id = true;
-    m_count = state.count;
-
-    res = pthread_mutex_unlock(&m_mutex);
-    assert(res == 0);
-}
-
-void recursive_timed_mutex::do_unlock(cv_state& state)
-{
-    int res = 0;
-    res = pthread_mutex_lock(&m_mutex);
-    assert(res == 0);
-
-    assert(m_valid_id);
-    m_valid_id = false;
-
-    res = pthread_cond_signal(&m_unlocked);
-    assert(res == 0);
-
-    state.pmutex = &m_mutex;
-    state.count = m_count;
-    m_count = 0;
-}
-#elif defined(BOOST_HAS_MPTASKS)
-
-using threads::mac::detail::safe_enter_critical_region;
-
-
-recursive_mutex::recursive_mutex()
-    : m_count(0)
-{
-}
-
-recursive_mutex::~recursive_mutex()
-{
-}
-
-void recursive_mutex::do_lock()
-{
-    OSStatus lStatus = noErr;
-    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
-        m_mutex_mutex);
-    assert(lStatus == noErr);
-
-    if (++m_count > 1)
-    {
-        lStatus = MPExitCriticalRegion(m_mutex);
-        assert(lStatus == noErr);
-    }
-}
-
-void recursive_mutex::do_unlock()
-{
-    if (--m_count == 0)
-    {
-        OSStatus lStatus = noErr;
-        lStatus = MPExitCriticalRegion(m_mutex);
-        assert(lStatus == noErr);
-    }
-}
-
-void recursive_mutex::do_lock(cv_state& state)
-{
-    OSStatus lStatus = noErr;
-    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
-        m_mutex_mutex);
-    assert(lStatus == noErr);
-
-    m_count = state;
-}
-
-void recursive_mutex::do_unlock(cv_state& state)
-{
-    state = m_count;
-    m_count = 0;
-
-    OSStatus lStatus = noErr;
-    lStatus = MPExitCriticalRegion(m_mutex);
-    assert(lStatus == noErr);
-}
-
-recursive_try_mutex::recursive_try_mutex()
-    : m_count(0)
-{
-}
-
-recursive_try_mutex::~recursive_try_mutex()
-{
-}
-
-void recursive_try_mutex::do_lock()
-{
-    OSStatus lStatus = noErr;
-    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
-        m_mutex_mutex);
-    assert(lStatus == noErr);
-
-    if (++m_count > 1)
-    {
-        lStatus = MPExitCriticalRegion(m_mutex);
-        assert(lStatus == noErr);
-    }
-}
-
-bool recursive_try_mutex::do_trylock()
-{
-    OSStatus lStatus = noErr;
-    lStatus = MPEnterCriticalRegion(m_mutex, kDurationImmediate);
-    assert(lStatus == noErr || lStatus == kMPTimeoutErr);
-
-    if (lStatus == noErr)
-    {
-        if (++m_count > 1)
-        {
-            lStatus = MPExitCriticalRegion(m_mutex);
-            assert(lStatus == noErr);
-        }
-        return true;
-    }
-    return false;
-}
-
-void recursive_try_mutex::do_unlock()
-{
-    if (--m_count == 0)
-    {
-        OSStatus lStatus = noErr;
-        lStatus = MPExitCriticalRegion(m_mutex);
-        assert(lStatus == noErr);
-    }
-}
-
-void recursive_try_mutex::do_lock(cv_state& state)
-{
-    OSStatus lStatus = noErr;
-    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
-        m_mutex_mutex);
-    assert(lStatus == noErr);
-
-    m_count = state;
-}
-
-void recursive_try_mutex::do_unlock(cv_state& state)
-{
-    state = m_count;
-    m_count = 0;
-
-    OSStatus lStatus = noErr;
-    lStatus = MPExitCriticalRegion(m_mutex);
-    assert(lStatus == noErr);
-}
-
-recursive_timed_mutex::recursive_timed_mutex()
-    : m_count(0)
-{
-}
-
-recursive_timed_mutex::~recursive_timed_mutex()
-{
-}
-
-void recursive_timed_mutex::do_lock()
-{
-    OSStatus lStatus = noErr;
-    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
-        m_mutex_mutex);
-    assert(lStatus == noErr);
-
-    if (++m_count > 1)
-    {
-        lStatus = MPExitCriticalRegion(m_mutex);
-        assert(lStatus == noErr);
-    }
-}
-
-bool recursive_timed_mutex::do_trylock()
-{
-    OSStatus lStatus = noErr;
-    lStatus = MPEnterCriticalRegion(m_mutex, kDurationImmediate);
-    assert(lStatus == noErr || lStatus == kMPTimeoutErr);
-
-    if (lStatus == noErr)
-    {
-        if (++m_count > 1)
-        {
-            lStatus = MPExitCriticalRegion(m_mutex);
-            assert(lStatus == noErr);
-        }
-        return true;
-    }
-    return false;
-}
-
-bool recursive_timed_mutex::do_timedlock(const xtime& xt)
-{
-    int microseconds;
-    to_microduration(xt, microseconds);
-    Duration lDuration = kDurationMicrosecond * microseconds;
-
-    OSStatus lStatus = noErr;
-    lStatus = safe_enter_critical_region(m_mutex, lDuration, m_mutex_mutex);
-    assert(lStatus == noErr || lStatus == kMPTimeoutErr);
-
-    if (lStatus == noErr)
-    {
-        if (++m_count > 1)
-        {
-            lStatus = MPExitCriticalRegion(m_mutex);
-            assert(lStatus == noErr);
-        }
-        return true;
-    }
-    return false;
-}
-
-void recursive_timed_mutex::do_unlock()
-{
-    if (--m_count == 0)
-    {
-        OSStatus lStatus = noErr;
-        lStatus = MPExitCriticalRegion(m_mutex);
-        assert(lStatus == noErr);
-    }
-}
-
-void recursive_timed_mutex::do_lock(cv_state& state)
-{
-    OSStatus lStatus = noErr;
-    lStatus = safe_enter_critical_region(m_mutex, kDurationForever,
-        m_mutex_mutex);
-    assert(lStatus == noErr);
-
-    m_count = state;
-}
-
-void recursive_timed_mutex::do_unlock(cv_state& state)
-{
-    state = m_count;
-    m_count = 0;
-
-    OSStatus lStatus = noErr;
-    lStatus = MPExitCriticalRegion(m_mutex);
-    assert(lStatus == noErr);
-}
-#endif
-
-} // namespace boost
-
-// Change Log:
-//   8 Feb 01  WEKEMPF Initial version.
Modified: trunk/libs/thread/test/Jamfile.v2
==============================================================================
--- trunk/libs/thread/test/Jamfile.v2	(original)
+++ trunk/libs/thread/test/Jamfile.v2	2007-10-10 11:33:49 EDT (Wed, 10 Oct 2007)
@@ -40,6 +40,7 @@
           [ thread-run test_once.cpp ]
           [ thread-run test_xtime.cpp ]
           [ thread-run test_barrier.cpp ]		   
-#          [ thread-run test_read_write_mutex.cpp ]
+          [ thread-run test_shared_mutex.cpp ]
+          [ thread-run test_lock_concept.cpp ]
     ;
 }
Added: trunk/libs/thread/test/test_lock_concept.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/test_lock_concept.cpp	2007-10-10 11:33:49 EDT (Wed, 10 Oct 2007)
@@ -0,0 +1,173 @@
+// (C) Copyright 2006-7 Anthony Williams
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include <boost/test/test_case_template.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+
+template<typename Mutex,typename Lock>
+struct test_initially_locked
+{
+    void operator()() const
+    {
+        Mutex m;
+        Lock lock(m);
+        
+        BOOST_CHECK(lock);
+        BOOST_CHECK(lock.owns_lock());
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_initially_unlocked_with_defer_lock_parameter
+{
+    void operator()() const
+    {
+        Mutex m;
+        Lock lock(m,boost::defer_lock);
+        
+        BOOST_CHECK(!lock);
+        BOOST_CHECK(!lock.owns_lock());
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_initially_locked_with_adopt_lock_parameter
+{
+    void operator()() const
+    {
+        Mutex m;
+        m.lock();
+        Lock lock(m,boost::adopt_lock);
+        
+        BOOST_CHECK(lock);
+        BOOST_CHECK(lock.owns_lock());
+    }
+};
+
+
+template<typename Mutex,typename Lock>
+struct test_unlocked_after_unlock_called
+{
+    void operator()() const
+    {
+        Mutex m;
+        Lock lock(m);
+        lock.unlock();
+        BOOST_CHECK(!lock);
+        BOOST_CHECK(!lock.owns_lock());
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_locked_after_lock_called
+{
+    void operator()() const
+    {
+        Mutex m;
+        Lock lock(m,boost::defer_lock);
+        lock.lock();
+        BOOST_CHECK(lock);
+        BOOST_CHECK(lock.owns_lock());
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_locked_after_try_lock_called
+{
+    void operator()() const
+    {
+        Mutex m;
+        Lock lock(m,boost::defer_lock);
+        lock.try_lock();
+        BOOST_CHECK(lock);
+        BOOST_CHECK(lock.owns_lock());
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_throws_if_lock_called_when_already_locked
+{
+    void operator()() const
+    {
+        Mutex m;
+        Lock lock(m);
+        
+        BOOST_CHECK_THROW( lock.lock(), boost::lock_error );
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_throws_if_try_lock_called_when_already_locked
+{
+    void operator()() const
+    {
+        Mutex m;
+        Lock lock(m);
+        
+        BOOST_CHECK_THROW( lock.try_lock(), boost::lock_error );
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_throws_if_unlock_called_when_already_unlocked
+{
+    void operator()() const
+    {
+        Mutex m;
+        Lock lock(m);
+        lock.unlock();
+        
+        BOOST_CHECK_THROW( lock.unlock(), boost::lock_error );
+    }
+};
+
+BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_scoped_lock_concept,Mutex)
+{
+    typedef typename Mutex::scoped_lock Lock;
+    
+    test_initially_locked<Mutex,Lock>()();
+    test_initially_unlocked_with_defer_lock_parameter<Mutex,Lock>()();
+    test_initially_locked_with_adopt_lock_parameter<Mutex,Lock>()();
+    test_unlocked_after_unlock_called<Mutex,Lock>()();
+    test_locked_after_lock_called<Mutex,Lock>()();
+    test_throws_if_lock_called_when_already_locked<Mutex,Lock>()();
+    test_throws_if_unlock_called_when_already_unlocked<Mutex,Lock>()();
+}
+
+BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_scoped_try_lock_concept,Mutex)
+{
+    typedef typename Mutex::scoped_try_lock Lock;
+    
+    test_initially_locked<Mutex,Lock>()();
+    test_initially_unlocked_with_defer_lock_parameter<Mutex,Lock>()();
+    test_initially_locked_with_adopt_lock_parameter<Mutex,Lock>()();
+    test_unlocked_after_unlock_called<Mutex,Lock>()();
+    test_locked_after_lock_called<Mutex,Lock>()();
+    test_locked_after_try_lock_called<Mutex,Lock>()();
+    test_throws_if_lock_called_when_already_locked<Mutex,Lock>()();
+    test_throws_if_try_lock_called_when_already_locked<Mutex,Lock>()();
+    test_throws_if_unlock_called_when_already_unlocked<Mutex,Lock>()();
+}
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: lock concept test suite");
+
+    typedef boost::mpl::vector<boost::mutex,boost::try_mutex,boost::timed_mutex,
+        boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types;
+    
+    test->add(BOOST_TEST_CASE_TEMPLATE(test_scoped_lock_concept,mutex_types));
+
+    typedef boost::mpl::vector<boost::try_mutex,boost::timed_mutex,
+        boost::recursive_try_mutex,boost::recursive_timed_mutex> try_mutex_types;
+
+    test->add(BOOST_TEST_CASE_TEMPLATE(test_scoped_try_lock_concept,try_mutex_types));
+
+    return test;
+}
Added: trunk/libs/thread/test/test_shared_mutex.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/thread/test/test_shared_mutex.cpp	2007-10-10 11:33:49 EDT (Wed, 10 Oct 2007)
@@ -0,0 +1,460 @@
+// (C) Copyright 2006-7 Anthony Williams
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/xtime.hpp>
+#include "util.inl"
+
+#define CHECK_LOCKED_VALUE_EQUAL(mutex_name,value,expected_value)    \
+    {                                                                \
+        boost::mutex::scoped_lock lock(mutex_name);                  \
+        BOOST_CHECK_EQUAL(value,expected_value);                     \
+    }
+
+
+namespace
+{
+    template<typename lock_type>
+    class locking_thread
+    {
+        boost::shared_mutex& rw_mutex;
+        unsigned& unblocked_count;
+        unsigned& simultaneous_running_count;
+        unsigned& max_simultaneous_running;
+        boost::mutex& unblocked_count_mutex;
+        boost::mutex& finish_mutex;
+    public:
+        locking_thread(boost::shared_mutex& rw_mutex_,
+                       unsigned& unblocked_count_,
+                       boost::mutex& unblocked_count_mutex_,
+                       boost::mutex& finish_mutex_,
+                       unsigned& simultaneous_running_count_,
+                       unsigned& max_simultaneous_running_):
+            rw_mutex(rw_mutex_),
+            unblocked_count(unblocked_count_),
+            unblocked_count_mutex(unblocked_count_mutex_),
+            finish_mutex(finish_mutex_),
+            simultaneous_running_count(simultaneous_running_count_),
+            max_simultaneous_running(max_simultaneous_running_)
+        {}
+        
+        void operator()()
+        {
+            // acquire lock
+            lock_type lock(rw_mutex);
+            
+            // increment count to show we're unblocked
+            {
+                boost::mutex::scoped_lock ublock(unblocked_count_mutex);
+                ++unblocked_count;
+                ++simultaneous_running_count;
+                if(simultaneous_running_count>max_simultaneous_running)
+                {
+                    max_simultaneous_running=simultaneous_running_count;
+                }
+            }
+            
+            // wait to finish
+            boost::mutex::scoped_lock finish_lock(finish_mutex);
+            {
+                boost::mutex::scoped_lock ublock(unblocked_count_mutex);
+                --simultaneous_running_count;
+            }
+        }
+    };
+    
+}
+
+
+void test_multiple_readers()
+{
+    unsigned const number_of_threads=100;
+    
+    boost::thread_group pool;
+
+    boost::shared_mutex rw_mutex;
+    unsigned unblocked_count=0;
+    unsigned simultaneous_running_count=0;
+    unsigned max_simultaneous_running=0;
+    boost::mutex unblocked_count_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    
+    for(unsigned i=0;i<number_of_threads;++i)
+    {
+        pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,finish_mutex,simultaneous_running_count,max_simultaneous_running));
+    }
+
+    boost::thread::sleep(delay(1));
+
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,number_of_threads);
+
+    finish_lock.unlock();
+
+    pool.join_all();
+
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,number_of_threads);
+}
+
+void test_only_one_writer_permitted()
+{
+    unsigned const number_of_threads=100;
+    
+    boost::thread_group pool;
+
+    boost::shared_mutex rw_mutex;
+    unsigned unblocked_count=0;
+    unsigned simultaneous_running_count=0;
+    unsigned max_simultaneous_running=0;
+    boost::mutex unblocked_count_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    
+    for(unsigned i=0;i<number_of_threads;++i)
+    {
+        pool.create_thread(locking_thread<boost::unique_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,finish_mutex,simultaneous_running_count,max_simultaneous_running));
+    }
+
+    boost::thread::sleep(delay(1));
+
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
+
+    finish_lock.unlock();
+
+    pool.join_all();
+
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,number_of_threads);
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,1);
+}
+
+void test_reader_blocks_writer()
+{
+    boost::thread_group pool;
+
+    boost::shared_mutex rw_mutex;
+    unsigned unblocked_count=0;
+    unsigned simultaneous_running_count=0;
+    unsigned max_simultaneous_running=0;
+    boost::mutex unblocked_count_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    
+    pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,finish_mutex,simultaneous_running_count,max_simultaneous_running));
+    boost::thread::sleep(delay(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
+    pool.create_thread(locking_thread<boost::unique_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,finish_mutex,simultaneous_running_count,max_simultaneous_running));
+    boost::thread::sleep(delay(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
+
+    finish_lock.unlock();
+
+    pool.join_all();
+
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,2U);
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,1);
+}
+
+void test_unlocking_writer_unblocks_all_readers()
+{
+    boost::thread_group pool;
+
+    boost::shared_mutex rw_mutex;
+    boost::unique_lock<boost::shared_mutex>  write_lock(rw_mutex);
+    unsigned unblocked_count=0;
+    unsigned simultaneous_running_count=0;
+    unsigned max_simultaneous_running=0;
+    boost::mutex unblocked_count_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+
+    unsigned const reader_count=100;
+
+    for(unsigned i=0;i<reader_count;++i)
+    {
+        pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,finish_mutex,simultaneous_running_count,max_simultaneous_running));
+    }
+    boost::thread::sleep(delay(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,0U);
+
+    write_lock.unlock();
+    
+    boost::thread::sleep(delay(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count);
+
+    finish_lock.unlock();
+    pool.join_all();
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,reader_count);
+}
+
+void test_unlocking_last_reader_only_unblocks_one_writer()
+{
+    boost::thread_group pool;
+
+    boost::shared_mutex rw_mutex;
+    unsigned unblocked_count=0;
+    unsigned simultaneous_running_readers=0;
+    unsigned max_simultaneous_readers=0;
+    unsigned simultaneous_running_writers=0;
+    unsigned max_simultaneous_writers=0;
+    boost::mutex unblocked_count_mutex;
+    boost::mutex finish_reading_mutex;
+    boost::mutex::scoped_lock finish_reading_lock(finish_reading_mutex);
+    boost::mutex finish_writing_mutex;
+    boost::mutex::scoped_lock finish_writing_lock(finish_writing_mutex);
+
+    unsigned const reader_count=100;
+    unsigned const writer_count=100;
+
+    for(unsigned i=0;i<reader_count;++i)
+    {
+        pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,finish_reading_mutex,simultaneous_running_readers,max_simultaneous_readers));
+    }
+    for(unsigned i=0;i<writer_count;++i)
+    {
+        pool.create_thread(locking_thread<boost::unique_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,finish_writing_mutex,simultaneous_running_writers,max_simultaneous_writers));
+    }
+    boost::thread::sleep(delay(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count);
+
+    finish_reading_lock.unlock();
+
+    boost::thread::sleep(delay(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+1);
+
+    finish_writing_lock.unlock();
+    pool.join_all();
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+writer_count);
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_readers,reader_count);
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_writers,1);
+}
+
+void test_only_one_upgrade_lock_permitted()
+{
+    unsigned const number_of_threads=100;
+    
+    boost::thread_group pool;
+
+    boost::shared_mutex rw_mutex;
+    unsigned unblocked_count=0;
+    unsigned simultaneous_running_count=0;
+    unsigned max_simultaneous_running=0;
+    boost::mutex unblocked_count_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    
+    for(unsigned i=0;i<number_of_threads;++i)
+    {
+        pool.create_thread(locking_thread<boost::upgrade_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,finish_mutex,simultaneous_running_count,max_simultaneous_running));
+    }
+
+    boost::thread::sleep(delay(1));
+
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
+
+    finish_lock.unlock();
+
+    pool.join_all();
+
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,number_of_threads);
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,1);
+}
+
+void test_can_lock_upgrade_if_currently_locked_shared()
+{
+    boost::thread_group pool;
+
+    boost::shared_mutex rw_mutex;
+    unsigned unblocked_count=0;
+    unsigned simultaneous_running_count=0;
+    unsigned max_simultaneous_running=0;
+    boost::mutex unblocked_count_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+
+    unsigned const reader_count=100;
+
+    for(unsigned i=0;i<reader_count;++i)
+    {
+        pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,finish_mutex,simultaneous_running_count,max_simultaneous_running));
+    }
+    pool.create_thread(locking_thread<boost::upgrade_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,finish_mutex,simultaneous_running_count,max_simultaneous_running));
+    boost::thread::sleep(delay(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+1);
+
+    finish_lock.unlock();
+    pool.join_all();
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+1);
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,reader_count+1);
+}
+
+namespace
+{
+    class simple_writing_thread
+    {
+        boost::shared_mutex& rwm;
+        boost::mutex& finish_mutex;
+        boost::mutex& unblocked_mutex;
+        unsigned& unblocked_count;
+        
+    public:
+        simple_writing_thread(boost::shared_mutex& rwm_,
+                              boost::mutex& finish_mutex_,
+                              boost::mutex& unblocked_mutex_,
+                              unsigned& unblocked_count_):
+            rwm(rwm_),finish_mutex(finish_mutex_),
+            unblocked_mutex(unblocked_mutex_),unblocked_count(unblocked_count_)
+        {}
+        
+        void operator()()
+        {
+            boost::unique_lock<boost::shared_mutex>  lk(rwm);
+            
+            {
+                boost::mutex::scoped_lock ulk(unblocked_mutex);
+                ++unblocked_count;
+            }
+            
+            boost::mutex::scoped_lock flk(finish_mutex);
+        }
+    };
+}
+
+void test_if_other_thread_has_write_lock_try_lock_shared_returns_false()
+{
+
+    boost::shared_mutex rw_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex unblocked_mutex;
+    unsigned unblocked_count=0;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+    boost::thread::sleep(delay(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1);
+
+    bool const try_succeeded=rw_mutex.try_lock_shared();
+    BOOST_CHECK(!try_succeeded);
+    if(try_succeeded)
+    {
+        rw_mutex.unlock_shared();
+    }
+
+    finish_lock.unlock();
+    writer.join();
+}
+
+void test_if_no_thread_has_lock_try_lock_shared_returns_true()
+{
+    boost::shared_mutex rw_mutex;
+    bool const try_succeeded=rw_mutex.try_lock_shared();
+    BOOST_CHECK(try_succeeded);
+    if(try_succeeded)
+    {
+        rw_mutex.unlock_shared();
+    }
+}
+
+namespace
+{
+    class simple_reading_thread
+    {
+        boost::shared_mutex& rwm;
+        boost::mutex& finish_mutex;
+        boost::mutex& unblocked_mutex;
+        unsigned& unblocked_count;
+        
+    public:
+        simple_reading_thread(boost::shared_mutex& rwm_,
+                              boost::mutex& finish_mutex_,
+                              boost::mutex& unblocked_mutex_,
+                              unsigned& unblocked_count_):
+            rwm(rwm_),finish_mutex(finish_mutex_),
+            unblocked_mutex(unblocked_mutex_),unblocked_count(unblocked_count_)
+        {}
+        
+        void operator()()
+        {
+            boost::shared_lock<boost::shared_mutex>  lk(rwm);
+            
+            {
+                boost::mutex::scoped_lock ulk(unblocked_mutex);
+                ++unblocked_count;
+            }
+            
+            boost::mutex::scoped_lock flk(finish_mutex);
+        }
+    };
+}
+
+void test_if_other_thread_has_shared_lock_try_lock_shared_returns_true()
+{
+
+    boost::shared_mutex rw_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex unblocked_mutex;
+    unsigned unblocked_count=0;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    boost::thread writer(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+    boost::thread::sleep(delay(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1);
+
+    bool const try_succeeded=rw_mutex.try_lock_shared();
+    BOOST_CHECK(try_succeeded);
+    if(try_succeeded)
+    {
+        rw_mutex.unlock_shared();
+    }
+
+    finish_lock.unlock();
+    writer.join();
+}
+
+void test_timed_lock_shared_times_out_if_write_lock_held()
+{
+    boost::shared_mutex rw_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex unblocked_mutex;
+    unsigned unblocked_count=0;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+    boost::thread::sleep(delay(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1);
+
+    boost::system_time const start=boost::get_system_time();
+    boost::system_time const timeout=start+boost::posix_time::milliseconds(100);
+    bool const timed_lock_succeeded=rw_mutex.timed_lock_shared(timeout);
+    BOOST_CHECK(timeout<=boost::get_system_time());
+    BOOST_CHECK(!timed_lock_succeeded);
+    if(timed_lock_succeeded)
+    {
+        rw_mutex.unlock_shared();
+    }
+
+    finish_lock.unlock();
+    writer.join();
+}
+
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: shared_mutex test suite");
+
+    test->add(BOOST_TEST_CASE(&test_multiple_readers));
+    test->add(BOOST_TEST_CASE(&test_only_one_writer_permitted));
+    test->add(BOOST_TEST_CASE(&test_reader_blocks_writer));
+    test->add(BOOST_TEST_CASE(&test_unlocking_writer_unblocks_all_readers));
+    test->add(BOOST_TEST_CASE(&test_unlocking_last_reader_only_unblocks_one_writer));
+    test->add(BOOST_TEST_CASE(&test_only_one_upgrade_lock_permitted));
+    test->add(BOOST_TEST_CASE(&test_can_lock_upgrade_if_currently_locked_shared));
+    test->add(BOOST_TEST_CASE(&test_if_other_thread_has_write_lock_try_lock_shared_returns_false));
+    test->add(BOOST_TEST_CASE(&test_if_no_thread_has_lock_try_lock_shared_returns_true));
+    test->add(BOOST_TEST_CASE(&test_if_other_thread_has_shared_lock_try_lock_shared_returns_true));
+    test->add(BOOST_TEST_CASE(&test_timed_lock_shared_times_out_if_write_lock_held));
+
+    return test;
+}