Boost logo

Boost-Commit :

From: anthony_at_[hidden]
Date: 2007-12-21 06:51:07


Author: anthonyw
Date: 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
New Revision: 42230
URL: http://svn.boost.org/trac/boost/changeset/42230

Log:
Merged latest changes to boost.thread over from trunk
Added:
   branches/release/libs/thread/test/condition_test_common.hpp
      - copied unchanged from r42229, /trunk/libs/thread/test/condition_test_common.hpp
   branches/release/libs/thread/test/shared_mutex_locking_thread.hpp
      - copied unchanged from r42229, /trunk/libs/thread/test/shared_mutex_locking_thread.hpp
   branches/release/libs/thread/test/test_condition_notify_all.cpp
      - copied unchanged from r42229, /trunk/libs/thread/test/test_condition_notify_all.cpp
   branches/release/libs/thread/test/test_condition_notify_one.cpp
      - copied unchanged from r42229, /trunk/libs/thread/test/test_condition_notify_one.cpp
   branches/release/libs/thread/test/test_condition_timed_wait_times_out.cpp
      - copied unchanged from r42229, /trunk/libs/thread/test/test_condition_timed_wait_times_out.cpp
   branches/release/libs/thread/test/test_hardware_concurrency.cpp
      - copied unchanged from r42229, /trunk/libs/thread/test/test_hardware_concurrency.cpp
   branches/release/libs/thread/test/test_move_function.cpp
      - copied unchanged from r42229, /trunk/libs/thread/test/test_move_function.cpp
   branches/release/libs/thread/test/test_shared_mutex_part_2.cpp
      - copied unchanged from r42229, /trunk/libs/thread/test/test_shared_mutex_part_2.cpp
   branches/release/libs/thread/test/test_thread_id.cpp
      - copied unchanged from r42229, /trunk/libs/thread/test/test_thread_id.cpp
   branches/release/libs/thread/test/test_thread_move.cpp
      - copied unchanged from r42229, /trunk/libs/thread/test/test_thread_move.cpp
Text files modified:
   branches/release/boost/thread/detail/config.hpp | 5
   branches/release/boost/thread/detail/move.hpp | 28 +-
   branches/release/boost/thread/locks.hpp | 114 ++++++++++++--
   branches/release/boost/thread/pthread/condition_variable.hpp | 16 +
   branches/release/boost/thread/pthread/condition_variable_fwd.hpp | 16 +
   branches/release/boost/thread/pthread/once.hpp | 18 +-
   branches/release/boost/thread/pthread/thread.hpp | 86 +++++++---
   branches/release/boost/thread/pthread/thread_data.hpp | 9
   branches/release/boost/thread/pthread/tss.hpp | 1
   branches/release/boost/thread/win32/condition_variable.hpp | 157 +++++++++++++------
   branches/release/boost/thread/win32/shared_mutex.hpp | 8
   branches/release/boost/thread/win32/thread.hpp | 110 +++++++++++++-
   branches/release/boost/thread/win32/thread_primitives.hpp | 3
   branches/release/libs/thread/build/Jamfile.v2 | 5
   branches/release/libs/thread/src/pthread/once.cpp | 10
   branches/release/libs/thread/src/pthread/thread.cpp | 76 ++++++++-
   branches/release/libs/thread/src/win32/thread.cpp | 155 ++++++++++++++++---
   branches/release/libs/thread/src/win32/tss_pe.cpp | 3
   branches/release/libs/thread/test/Jamfile.v2 | 9 +
   branches/release/libs/thread/test/test_barrier.cpp | 2
   branches/release/libs/thread/test/test_condition.cpp | 84 ++--------
   branches/release/libs/thread/test/test_mutex.cpp | 14 +
   branches/release/libs/thread/test/test_once.cpp | 1
   branches/release/libs/thread/test/test_shared_mutex.cpp | 310 ---------------------------------------
   branches/release/libs/thread/test/test_tss.cpp | 14 -
   branches/release/libs/thread/test/util.inl | 21 ++
   26 files changed, 697 insertions(+), 578 deletions(-)

Modified: branches/release/boost/thread/detail/config.hpp
==============================================================================
--- branches/release/boost/thread/detail/config.hpp (original)
+++ branches/release/boost/thread/detail/config.hpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -17,8 +17,7 @@
 # pragma warn -8066 // Unreachable code
 #endif
 
-// insist on threading support being available:
-#include <boost/config/requires_threads.hpp>
+#include "platform.hpp"
 
 // compatibility with the rest of Boost's auto-linking code:
 #if defined(BOOST_THREAD_DYN_DLL) || defined(BOOST_ALL_DYN_LINK)
@@ -31,7 +30,7 @@
 #elif defined(BOOST_THREAD_USE_DLL) //Use dll
 #elif defined(BOOST_THREAD_USE_LIB) //Use lib
 #else //Use default
-# if defined(BOOST_HAS_WINTHREADS)
+# if defined(BOOST_THREAD_PLATFORM_WIN32)
 # if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)
             //For compilers supporting auto-tss cleanup
             //with Boost.Threads lib, use Boost.Threads lib

Modified: branches/release/boost/thread/detail/move.hpp
==============================================================================
--- branches/release/boost/thread/detail/move.hpp (original)
+++ branches/release/boost/thread/detail/move.hpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -8,25 +8,23 @@
 
 namespace boost
 {
- template<typename T>
- struct move_t
+ namespace detail
     {
- T& t;
- move_t(T& t_):
- t(t_)
- {}
-
- T* operator->() const
+ template<typename T>
+ struct thread_move_t
         {
- return &t;
- }
- };
+ T& t;
+ thread_move_t(T& t_):
+ t(t_)
+ {}
 
- template<typename T>
- move_t<T> move(T& t)
- {
- return move_t<T>(t);
+ T* operator->() const
+ {
+ return &t;
+ }
+ };
     }
+
 }
 
 

Modified: branches/release/boost/thread/locks.hpp
==============================================================================
--- branches/release/boost/thread/locks.hpp (original)
+++ branches/release/boost/thread/locks.hpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -86,21 +86,32 @@
         {
             timed_lock(target_time);
         }
- unique_lock(boost::move_t<unique_lock<Mutex> > other):
+ unique_lock(detail::thread_move_t<unique_lock<Mutex> > other):
             m(other->m),is_locked(other->is_locked)
         {
             other->is_locked=false;
+ other->m=0;
         }
- unique_lock(boost::move_t<upgrade_lock<Mutex> > other);
+ unique_lock(detail::thread_move_t<upgrade_lock<Mutex> > other);
 
- unique_lock& operator=(boost::move_t<unique_lock<Mutex> > other)
+ operator detail::thread_move_t<unique_lock<Mutex> >()
+ {
+ return move();
+ }
+
+ detail::thread_move_t<unique_lock<Mutex> > move()
+ {
+ return detail::thread_move_t<unique_lock<Mutex> >(*this);
+ }
+
+ unique_lock& operator=(detail::thread_move_t<unique_lock<Mutex> > other)
         {
             unique_lock temp(other);
             swap(temp);
             return *this;
         }
 
- unique_lock& operator=(boost::move_t<upgrade_lock<Mutex> > other)
+ unique_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other)
         {
             unique_lock temp(other);
             swap(temp);
@@ -112,7 +123,7 @@
             std::swap(m,other.m);
             std::swap(is_locked,other.is_locked);
         }
- void swap(boost::move_t<unique_lock<Mutex> > other)
+ void swap(detail::thread_move_t<unique_lock<Mutex> > other)
         {
             std::swap(m,other->m);
             std::swap(is_locked,other->is_locked);
@@ -197,6 +208,18 @@
     };
 
     template<typename Mutex>
+ inline detail::thread_move_t<unique_lock<Mutex> > move(unique_lock<Mutex> & x)
+ {
+ return x.move();
+ }
+
+ template<typename Mutex>
+ inline detail::thread_move_t<unique_lock<Mutex> > move(detail::thread_move_t<unique_lock<Mutex> > x)
+ {
+ return x;
+ }
+
+ template<typename Mutex>
     class shared_lock
     {
     protected:
@@ -228,13 +251,13 @@
             timed_lock(target_time);
         }
 
- shared_lock(boost::move_t<shared_lock<Mutex> > other):
+ shared_lock(detail::thread_move_t<shared_lock<Mutex> > other):
             m(other->m),is_locked(other->is_locked)
         {
             other->is_locked=false;
         }
 
- shared_lock(boost::move_t<unique_lock<Mutex> > other):
+ shared_lock(detail::thread_move_t<unique_lock<Mutex> > other):
             m(other->m),is_locked(other->is_locked)
         {
             other->is_locked=false;
@@ -244,7 +267,7 @@
             }
         }
 
- shared_lock(boost::move_t<upgrade_lock<Mutex> > other):
+ shared_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
             m(other->m),is_locked(other->is_locked)
         {
             other->is_locked=false;
@@ -254,21 +277,32 @@
             }
         }
 
- shared_lock& operator=(boost::move_t<shared_lock<Mutex> > other)
+ operator detail::thread_move_t<shared_lock<Mutex> >()
+ {
+ return move();
+ }
+
+ detail::thread_move_t<shared_lock<Mutex> > move()
+ {
+ return detail::thread_move_t<shared_lock<Mutex> >(*this);
+ }
+
+
+ shared_lock& operator=(detail::thread_move_t<shared_lock<Mutex> > other)
         {
             shared_lock temp(other);
             swap(temp);
             return *this;
         }
 
- shared_lock& operator=(boost::move_t<unique_lock<Mutex> > other)
+ shared_lock& operator=(detail::thread_move_t<unique_lock<Mutex> > other)
         {
             shared_lock temp(other);
             swap(temp);
             return *this;
         }
 
- shared_lock& operator=(boost::move_t<upgrade_lock<Mutex> > other)
+ shared_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other)
         {
             shared_lock temp(other);
             swap(temp);
@@ -342,6 +376,19 @@
     };
 
     template<typename Mutex>
+ inline detail::thread_move_t<shared_lock<Mutex> > move(shared_lock<Mutex> & x)
+ {
+ return x.move();
+ }
+
+ template<typename Mutex>
+ inline detail::thread_move_t<shared_lock<Mutex> > move(detail::thread_move_t<shared_lock<Mutex> > x)
+ {
+ return x;
+ }
+
+
+ template<typename Mutex>
     class upgrade_lock
     {
     protected:
@@ -364,13 +411,13 @@
                 lock();
             }
         }
- upgrade_lock(boost::move_t<upgrade_lock<Mutex> > other):
+ upgrade_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
             m(other->m),is_locked(other->is_locked)
         {
             other->is_locked=false;
         }
 
- upgrade_lock(boost::move_t<unique_lock<Mutex> > other):
+ upgrade_lock(detail::thread_move_t<unique_lock<Mutex> > other):
             m(other->m),is_locked(other->is_locked)
         {
             other->is_locked=false;
@@ -380,14 +427,25 @@
             }
         }
 
- upgrade_lock& operator=(boost::move_t<upgrade_lock<Mutex> > other)
+ operator detail::thread_move_t<upgrade_lock<Mutex> >()
+ {
+ return move();
+ }
+
+ detail::thread_move_t<upgrade_lock<Mutex> > move()
+ {
+ return detail::thread_move_t<upgrade_lock<Mutex> >(*this);
+ }
+
+
+ upgrade_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other)
         {
             upgrade_lock temp(other);
             swap(temp);
             return *this;
         }
 
- upgrade_lock& operator=(boost::move_t<unique_lock<Mutex> > other)
+ upgrade_lock& operator=(detail::thread_move_t<unique_lock<Mutex> > other)
         {
             upgrade_lock temp(other);
             swap(temp);
@@ -452,8 +510,21 @@
         friend class unique_lock<Mutex>;
     };
 
+
+ template<typename Mutex>
+ inline detail::thread_move_t<upgrade_lock<Mutex> > move(upgrade_lock<Mutex> & x)
+ {
+ return x.move();
+ }
+
     template<typename Mutex>
- unique_lock<Mutex>::unique_lock(boost::move_t<upgrade_lock<Mutex> > other):
+ inline detail::thread_move_t<upgrade_lock<Mutex> > move(detail::thread_move_t<upgrade_lock<Mutex> > x)
+ {
+ return x;
+ }
+
+ template<typename Mutex>
+ unique_lock<Mutex>::unique_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
         m(other->m),is_locked(other->is_locked)
     {
         other->is_locked=false;
@@ -474,23 +545,23 @@
         upgrade_to_unique_lock& operator=(upgrade_to_unique_lock&);
     public:
         explicit upgrade_to_unique_lock(upgrade_lock<Mutex>& m_):
- source(&m_),exclusive(boost::move(*source))
+ source(&m_),exclusive(move(*source))
         {}
         ~upgrade_to_unique_lock()
         {
             if(source)
             {
- *source=boost::move(exclusive);
+ *source=move(exclusive);
             }
         }
 
- upgrade_to_unique_lock(boost::move_t<upgrade_to_unique_lock<Mutex> > other):
- source(other->source),exclusive(boost::move(other->exclusive))
+ upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other):
+ source(other->source),exclusive(move(other->exclusive))
         {
             other->source=0;
         }
         
- upgrade_to_unique_lock& operator=(boost::move_t<upgrade_to_unique_lock<Mutex> > other)
+ upgrade_to_unique_lock& operator=(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other)
         {
             upgrade_to_unique_lock temp(other);
             swap(temp);
@@ -515,6 +586,7 @@
             return exclusive.owns_lock();
         }
     };
+
 }
 
 #endif

Modified: branches/release/boost/thread/pthread/condition_variable.hpp
==============================================================================
--- branches/release/boost/thread/pthread/condition_variable.hpp (original)
+++ branches/release/boost/thread/pthread/condition_variable.hpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -5,11 +5,9 @@
 // http://www.boost.org/LICENSE_1_0.txt)
 // (C) Copyright 2007 Anthony Williams
 
-#include <boost/thread/mutex.hpp>
 #include <limits.h>
 #include <boost/assert.hpp>
 #include <algorithm>
-#include <boost/thread/thread_time.hpp>
 #include <pthread.h>
 #include "timespec.hpp"
 #include "pthread_mutex_scoped_lock.hpp"
@@ -145,11 +143,23 @@
             while (!pred())
             {
                 if(!timed_wait(m, wait_until))
- return false;
+ return pred();
             }
             return true;
         }
 
+ template<typename lock_type,typename predicate_type>
+ bool timed_wait(lock_type& m,xtime const& wait_until,predicate_type pred)
+ {
+ return timed_wait(m,system_time(wait_until),pred);
+ }
+
+ template<typename lock_type,typename duration_type,typename predicate_type>
+ bool timed_wait(lock_type& m,duration_type const& wait_duration,predicate_type pred)
+ {
+ return timed_wait(m,get_system_time()+wait_duration,pred);
+ }
+
         void notify_one()
         {
             boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);

Modified: branches/release/boost/thread/pthread/condition_variable_fwd.hpp
==============================================================================
--- branches/release/boost/thread/pthread/condition_variable_fwd.hpp (original)
+++ branches/release/boost/thread/pthread/condition_variable_fwd.hpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -6,8 +6,10 @@
 // (C) Copyright 2007 Anthony Williams
 
 #include <pthread.h>
+#include <boost/thread/mutex.hpp>
 #include <boost/thread/locks.hpp>
 #include <boost/thread/thread_time.hpp>
+#include <boost/thread/xtime.hpp>
 
 namespace boost
 {
@@ -39,11 +41,23 @@
             while (!pred())
             {
                 if(!timed_wait(m, wait_until))
- return false;
+ return pred();
             }
             return true;
         }
 
+ template<typename predicate_type>
+ bool timed_wait(unique_lock<mutex>& m,xtime const& wait_until,predicate_type pred)
+ {
+ return timed_wait(m,system_time(wait_until),pred);
+ }
+
+ template<typename duration_type,typename predicate_type>
+ bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration,predicate_type pred)
+ {
+ return timed_wait(m,get_system_time()+wait_duration,pred);
+ }
+
         void notify_one();
         void notify_all();
     };

Modified: branches/release/boost/thread/pthread/once.hpp
==============================================================================
--- branches/release/boost/thread/pthread/once.hpp (original)
+++ branches/release/boost/thread/pthread/once.hpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -14,8 +14,8 @@
 #include <pthread.h>
 #include <boost/assert.hpp>
 #include "pthread_mutex_scoped_lock.hpp"
-#include <boost/cstdint.hpp>
 #include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
+#include <boost/cstdint.hpp>
 
 namespace boost {
 
@@ -27,12 +27,12 @@
     namespace detail
     {
         BOOST_THREAD_DECL boost::uintmax_t& get_once_per_thread_epoch();
- extern BOOST_THREAD_DECL boost::uintmax_t once_global_epoch;
- extern BOOST_THREAD_DECL pthread_mutex_t once_epoch_mutex;
- extern BOOST_THREAD_DECL pthread_cond_t once_epoch_cv;
+ BOOST_THREAD_DECL extern boost::uintmax_t once_global_epoch;
+ BOOST_THREAD_DECL extern pthread_mutex_t once_epoch_mutex;
+ BOOST_THREAD_DECL extern pthread_cond_t once_epoch_cv;
     }
     
-#define BOOST_ONCE_INITIAL_FLAG_VALUE -1
+#define BOOST_ONCE_INITIAL_FLAG_VALUE 0
 #define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE}
 
 
@@ -42,15 +42,15 @@
     void call_once(once_flag& flag,Function f)
     {
         static boost::uintmax_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
- static boost::uintmax_t const being_initialized=uninitialized_flag-1;
+ static boost::uintmax_t const being_initialized=uninitialized_flag+1;
         boost::uintmax_t const epoch=flag.epoch;
         boost::uintmax_t& this_thread_epoch=detail::get_once_per_thread_epoch();
         
- if(epoch>this_thread_epoch)
+ if(epoch<this_thread_epoch)
         {
             pthread::pthread_mutex_scoped_lock lk(&detail::once_epoch_mutex);
 
- while(flag.epoch>=being_initialized)
+ while(flag.epoch<=being_initialized)
             {
                 if(flag.epoch==uninitialized_flag)
                 {
@@ -66,7 +66,7 @@
                         BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
                         throw;
                     }
- flag.epoch=++detail::once_global_epoch;
+ flag.epoch=--detail::once_global_epoch;
                     BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
                 }
                 else

Modified: branches/release/boost/thread/pthread/thread.hpp
==============================================================================
--- branches/release/boost/thread/pthread/thread.hpp (original)
+++ branches/release/boost/thread/pthread/thread.hpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -40,44 +40,62 @@
     {
         class thread_id
         {
- boost::optional<pthread_t> id;
-
+ private:
+ detail::thread_data_ptr thread_data;
+
+ thread_id(detail::thread_data_ptr thread_data_):
+ thread_data(thread_data_)
+ {}
             friend class boost::thread;
-
             friend thread_id this_thread::get_id();
-
- thread_id(pthread_t id_):
- id(id_)
- {}
-
         public:
- thread_id()
+ thread_id():
+ thread_data()
             {}
-
+
             bool operator==(const thread_id& y) const
             {
- return (id && y.id) && (pthread_equal(*id,*y.id)!=0);
+ return thread_data==y.thread_data;
             }
         
             bool operator!=(const thread_id& y) const
             {
- return !(*this==y);
+ return thread_data!=y.thread_data;
+ }
+
+ bool operator<(const thread_id& y) const
+ {
+ return thread_data<y.thread_data;
+ }
+
+ bool operator>(const thread_id& y) const
+ {
+ return y.thread_data<thread_data;
+ }
+
+ bool operator<=(const thread_id& y) const
+ {
+ return !(y.thread_data<thread_data);
+ }
+
+ bool operator>=(const thread_id& y) const
+ {
+ return !(thread_data<y.thread_data);
             }
 
             template<class charT, class traits>
             friend std::basic_ostream<charT, traits>&
             operator<<(std::basic_ostream<charT, traits>& os, const thread_id& x)
             {
- if(x.id)
+ if(x.thread_data)
                 {
- return os<<*x.id;
+ return os<<x.thread_data;
                 }
                 else
                 {
                     return os<<"{Not-any-thread}";
                 }
             }
-
         };
     }
 
@@ -97,7 +115,7 @@
             thread_data(F f_):
                 f(f_)
             {}
- thread_data(boost::move_t<F> f_):
+ thread_data(detail::thread_move_t<F> f_):
                 f(f_)
             {}
             
@@ -108,13 +126,13 @@
         };
         
         mutable boost::mutex thread_info_mutex;
- boost::shared_ptr<detail::thread_data_base> thread_info;
+ detail::thread_data_ptr thread_info;
 
         void start_thread();
         
- explicit thread(boost::shared_ptr<detail::thread_data_base> data);
+ explicit thread(detail::thread_data_ptr data);
 
- boost::shared_ptr<detail::thread_data_base> get_thread_info() const;
+ detail::thread_data_ptr get_thread_info() const;
         
     public:
         thread();
@@ -127,16 +145,16 @@
             start_thread();
         }
         template <class F>
- thread(boost::move_t<F> f):
+ thread(detail::thread_move_t<F> f):
             thread_info(new thread_data<F>(f))
         {
             start_thread();
         }
 
- explicit thread(boost::move_t<thread> x);
- thread& operator=(boost::move_t<thread> x);
- operator boost::move_t<thread>();
- boost::move_t<thread> move();
+ thread(detail::thread_move_t<thread> x);
+ thread& operator=(detail::thread_move_t<thread> x);
+ operator detail::thread_move_t<thread>();
+ detail::thread_move_t<thread> move();
 
         void swap(thread& x);
 
@@ -169,6 +187,17 @@
         bool interruption_requested() const;
     };
 
+ inline detail::thread_move_t<thread> move(thread& x)
+ {
+ return x.move();
+ }
+
+ inline detail::thread_move_t<thread> move(detail::thread_move_t<thread> x)
+ {
+ return x;
+ }
+
+
     template<typename F>
     struct thread::thread_data<boost::reference_wrapper<F> >:
         detail::thread_data_base
@@ -208,22 +237,19 @@
             ~restore_interruption();
         };
 
- BOOST_THREAD_DECL inline thread::id get_id()
- {
- return thread::id(pthread_self());
- }
+ BOOST_THREAD_DECL thread::id get_id();
 
         BOOST_THREAD_DECL void interruption_point();
         BOOST_THREAD_DECL bool interruption_enabled();
         BOOST_THREAD_DECL bool interruption_requested();
 
- BOOST_THREAD_DECL inline void yield()
+ inline void yield()
         {
             thread::yield();
         }
         
         template<typename TimeDuration>
- BOOST_THREAD_DECL inline void sleep(TimeDuration const& rel_time)
+ inline void sleep(TimeDuration const& rel_time)
         {
             thread::sleep(get_system_time()+rel_time);
         }

Modified: branches/release/boost/thread/pthread/thread_data.hpp
==============================================================================
--- branches/release/boost/thread/pthread/thread_data.hpp (original)
+++ branches/release/boost/thread/pthread/thread_data.hpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -7,6 +7,7 @@
 
 #include <boost/thread/detail/config.hpp>
 #include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
 #include <boost/thread/mutex.hpp>
 #include <boost/optional.hpp>
 #include <pthread.h>
@@ -21,10 +22,14 @@
     {
         struct thread_exit_callback_node;
         struct tss_data_node;
+
+ struct thread_data_base;
+ typedef boost::shared_ptr<thread_data_base> thread_data_ptr;
         
- struct thread_data_base
+ struct thread_data_base:
+ enable_shared_from_this<thread_data_base>
         {
- boost::shared_ptr<thread_data_base> self;
+ thread_data_ptr self;
             pthread_t thread_handle;
             boost::mutex data_mutex;
             boost::condition_variable done_condition;

Modified: branches/release/boost/thread/pthread/tss.hpp
==============================================================================
--- branches/release/boost/thread/pthread/tss.hpp (original)
+++ branches/release/boost/thread/pthread/tss.hpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -6,6 +6,7 @@
 // http://www.boost.org/LICENSE_1_0.txt)
 // (C) Copyright 2007 Anthony Williams
 
+#include <boost/thread/detail/config.hpp>
 #include <boost/shared_ptr.hpp>
 
 namespace boost

Modified: branches/release/boost/thread/win32/condition_variable.hpp
==============================================================================
--- branches/release/boost/thread/win32/condition_variable.hpp (original)
+++ branches/release/boost/thread/win32/condition_variable.hpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -13,6 +13,7 @@
 #include <boost/thread/thread.hpp>
 #include <boost/thread/thread_time.hpp>
 #include "interlocked_read.hpp"
+#include <boost/thread/xtime.hpp>
 
 namespace boost
 {
@@ -110,54 +111,65 @@
             };
             
 
+ template<typename lock_type>
+ void start_wait_loop_first_time(relocker<lock_type>& locker,
+ detail::win32::handle_manager& local_wake_sem)
+ {
+ locker.unlock();
+ if(!wake_sem)
+ {
+ wake_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+ BOOST_ASSERT(wake_sem);
+ }
+ local_wake_sem=detail::win32::duplicate_handle(wake_sem);
+
+ if(generations[0].notified)
+ {
+ shift_generations_down();
+ }
+ else if(!active_generation_count)
+ {
+ active_generation_count=1;
+ }
+ }
+
+ template<typename lock_type>
+ void start_wait_loop(relocker<lock_type>& locker,
+ detail::win32::handle_manager& local_wake_sem,
+ detail::win32::handle_manager& sem)
+ {
+ boost::mutex::scoped_lock internal_lock(internal_mutex);
+ detail::interlocked_write_release(&total_count,total_count+1);
+ if(!local_wake_sem)
+ {
+ start_wait_loop_first_time(locker,local_wake_sem);
+ }
+ if(!generations[0].semaphore)
+ {
+ generations[0].semaphore=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+ BOOST_ASSERT(generations[0].semaphore);
+ }
+ ++generations[0].count;
+ sem=detail::win32::duplicate_handle(generations[0].semaphore);
+ }
+
         protected:
             template<typename lock_type>
- bool do_wait(lock_type& lock,::boost::system_time const& wait_until)
+ bool do_wait(lock_type& lock,timeout wait_until)
             {
                 detail::win32::handle_manager local_wake_sem;
                 detail::win32::handle_manager sem;
- bool first_loop=true;
                 bool woken=false;
 
                 relocker<lock_type> locker(lock);
             
                 while(!woken)
                 {
+ start_wait_loop(locker,local_wake_sem,sem);
+
+ if(!this_thread::interruptible_wait(sem,wait_until))
                     {
- boost::mutex::scoped_lock internal_lock(internal_mutex);
- detail::interlocked_write_release(&total_count,total_count+1);
- if(first_loop)
- {
- locker.unlock();
- if(!wake_sem)
- {
- wake_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
- BOOST_ASSERT(wake_sem);
- }
- local_wake_sem=detail::win32::duplicate_handle(wake_sem);
-
- if(generations[0].notified)
- {
- shift_generations_down();
- }
- else if(!active_generation_count)
- {
- active_generation_count=1;
- }
-
- first_loop=false;
- }
- if(!generations[0].semaphore)
- {
- generations[0].semaphore=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
- BOOST_ASSERT(generations[0].semaphore);
- }
- ++generations[0].count;
- sem=detail::win32::duplicate_handle(generations[0].semaphore);
- }
- if(!this_thread::interruptible_wait(sem,::boost::detail::get_milliseconds_until(wait_until)))
- {
- break;
+ return false;
                     }
                 
                     unsigned long const woken_result=detail::win32::WaitForSingleObject(local_wake_sem,0);
@@ -167,6 +179,17 @@
                 }
                 return woken;
             }
+
+ template<typename lock_type,typename predicate_type>
+ bool do_wait(lock_type& m,timeout const& wait_until,predicate_type pred)
+ {
+ while (!pred())
+ {
+ if(!do_wait(m, wait_until))
+ return pred();
+ }
+ return true;
+ }
         
             basic_condition_variable(const basic_condition_variable& other);
             basic_condition_variable& operator=(const basic_condition_variable& other);
@@ -238,7 +261,7 @@
     public:
         void wait(unique_lock<mutex>& m)
         {
- do_wait(m,::boost::detail::get_system_time_sentinel());
+ do_wait(m,detail::timeout::sentinel());
         }
 
         template<typename predicate_type>
@@ -253,15 +276,30 @@
             return do_wait(m,wait_until);
         }
 
+ bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until)
+ {
+ return do_wait(m,system_time(wait_until));
+ }
+ template<typename duration_type>
+ bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration)
+ {
+ return do_wait(m,wait_duration.total_milliseconds());
+ }
+
         template<typename predicate_type>
         bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until,predicate_type pred)
         {
- while (!pred())
- {
- if(!timed_wait(m, wait_until))
- return false;
- }
- return true;
+ return do_wait(m,wait_until,pred);
+ }
+ template<typename predicate_type>
+ bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until,predicate_type pred)
+ {
+ return do_wait(m,system_time(wait_until),pred);
+ }
+ template<typename duration_type,typename predicate_type>
+ bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration,predicate_type pred)
+ {
+ return do_wait(m,wait_duration.total_milliseconds(),pred);
         }
     };
     
@@ -272,7 +310,7 @@
         template<typename lock_type>
         void wait(lock_type& m)
         {
- do_wait(m,::boost::detail::get_system_time_sentinel());
+ do_wait(m,detail::timeout::sentinel());
         }
 
         template<typename lock_type,typename predicate_type>
@@ -287,15 +325,34 @@
             return do_wait(m,wait_until);
         }
 
+ template<typename lock_type>
+ bool timed_wait(lock_type& m,boost::xtime const& wait_until)
+ {
+ return do_wait(m,system_time(wait_until));
+ }
+
+ template<typename lock_type,typename duration_type>
+ bool timed_wait(lock_type& m,duration_type const& wait_duration)
+ {
+ return do_wait(m,wait_duration.total_milliseconds());
+ }
+
         template<typename lock_type,typename predicate_type>
         bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred)
         {
- while (!pred())
- {
- if(!timed_wait(m, wait_until))
- return false;
- }
- return true;
+ return do_wait(m,wait_until,pred);
+ }
+
+ template<typename lock_type,typename predicate_type>
+ bool timed_wait(lock_type& m,boost::xtime const& wait_until,predicate_type pred)
+ {
+ return do_wait(m,system_time(wait_until),pred);
+ }
+
+ template<typename lock_type,typename duration_type,typename predicate_type>
+ bool timed_wait(lock_type& m,duration_type const& wait_duration,predicate_type pred)
+ {
+ return do_wait(m,wait_duration.total_milliseconds(),pred);
         }
     };
 

Modified: branches/release/boost/thread/win32/shared_mutex.hpp
==============================================================================
--- branches/release/boost/thread/win32/shared_mutex.hpp (original)
+++ branches/release/boost/thread/win32/shared_mutex.hpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -48,10 +48,10 @@
         }
 
         state_data state;
- void* semaphores[2];
- void* &unlock_sem;
- void* &exclusive_sem;
- void* upgrade_sem;
+ detail::win32::handle semaphores[2];
+ detail::win32::handle &unlock_sem;
+ detail::win32::handle &exclusive_sem;
+ detail::win32::handle upgrade_sem;
 
         void release_waiters(state_data old_state)
         {

Modified: branches/release/boost/thread/win32/thread.hpp
==============================================================================
--- branches/release/boost/thread/win32/thread.hpp (original)
+++ branches/release/boost/thread/win32/thread.hpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -19,6 +19,7 @@
 #include <list>
 #include <algorithm>
 #include <boost/ref.hpp>
+#include <boost/cstdint.hpp>
 
 namespace boost
 {
@@ -73,6 +74,82 @@
         };
 
         typedef boost::intrusive_ptr<detail::thread_data_base> thread_data_ptr;
+
+ struct timeout
+ {
+ unsigned long start;
+ uintmax_t milliseconds;
+ bool relative;
+ boost::system_time abs_time;
+
+ static unsigned long const max_non_infinite_wait=0xfffffffe;
+
+ timeout(uintmax_t milliseconds_):
+ start(win32::GetTickCount()),
+ milliseconds(milliseconds_),
+ relative(true),
+ abs_time(boost::get_system_time())
+ {}
+
+ timeout(boost::system_time const& abs_time_):
+ start(win32::GetTickCount()),
+ milliseconds(0),
+ relative(false),
+ abs_time(abs_time_)
+ {}
+
+ struct remaining_time
+ {
+ bool more;
+ unsigned long milliseconds;
+
+ remaining_time(uintmax_t remaining):
+ more(remaining>max_non_infinite_wait),
+ milliseconds(more?max_non_infinite_wait:(unsigned long)remaining)
+ {}
+ };
+
+ remaining_time remaining_milliseconds() const
+ {
+ if(is_sentinel())
+ {
+ return remaining_time(win32::infinite);
+ }
+ else if(relative)
+ {
+ unsigned long const now=win32::GetTickCount();
+ unsigned long const elapsed=now-start;
+ return remaining_time((elapsed<milliseconds)?(milliseconds-elapsed):0);
+ }
+ else
+ {
+ system_time const now=get_system_time();
+ if(abs_time<=now)
+ {
+ return remaining_time(0);
+ }
+ return remaining_time((abs_time-now).total_milliseconds()+1);
+ }
+ }
+
+ bool is_sentinel() const
+ {
+ return milliseconds==~uintmax_t(0);
+ }
+
+
+ static timeout sentinel()
+ {
+ return timeout(sentinel_type());
+ }
+ private:
+ struct sentinel_type
+ {};
+
+ explicit timeout(sentinel_type):
+ start(0),milliseconds(~uintmax_t(0)),relative(true)
+ {}
+ };
     }
 
     class BOOST_THREAD_DECL thread
@@ -92,7 +169,7 @@
             thread_data(F f_):
                 f(f_)
             {}
- thread_data(boost::move_t<F> f_):
+ thread_data(detail::thread_move_t<F> f_):
                 f(f_)
             {}
             
@@ -123,16 +200,16 @@
             start_thread();
         }
         template <class F>
- explicit thread(boost::move_t<F> f):
+ thread(detail::thread_move_t<F> f):
             thread_info(detail::heap_new<thread_data<F> >(f))
         {
             start_thread();
         }
 
- thread(boost::move_t<thread> x);
- thread& operator=(boost::move_t<thread> x);
- operator boost::move_t<thread>();
- boost::move_t<thread> move();
+ thread(detail::thread_move_t<thread> x);
+ thread& operator=(detail::thread_move_t<thread> x);
+ operator detail::thread_move_t<thread>();
+ detail::thread_move_t<thread> move();
 
         void swap(thread& x);
 
@@ -168,6 +245,16 @@
         bool interruption_requested() const;
     };
 
+ inline detail::thread_move_t<thread> move(thread& x)
+ {
+ return x.move();
+ }
+
+ inline detail::thread_move_t<thread> move(detail::thread_move_t<thread> x)
+ {
+ return x;
+ }
+
     template<typename F>
     struct thread::thread_data<boost::reference_wrapper<F> >:
         detail::thread_data_base
@@ -210,7 +297,7 @@
 
         thread::id BOOST_THREAD_DECL get_id();
 
- bool BOOST_THREAD_DECL interruptible_wait(detail::win32::handle handle_to_wait_for,unsigned long milliseconds);
+ bool BOOST_THREAD_DECL interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time);
         inline bool interruptible_wait(unsigned long milliseconds)
         {
             return interruptible_wait(detail::win32::invalid_handle_value,milliseconds);
@@ -277,7 +364,14 @@
         friend std::basic_ostream<charT, traits>&
         operator<<(std::basic_ostream<charT, traits>& os, const id& x)
         {
- return os<<x.thread_data;
+ if(x.thread_data)
+ {
+ return os<<x.thread_data;
+ }
+ else
+ {
+ return os<<"{Not-any-thread}";
+ }
         }
 
         void interrupt()

Modified: branches/release/boost/thread/win32/thread_primitives.hpp
==============================================================================
--- branches/release/boost/thread/win32/thread_primitives.hpp (original)
+++ branches/release/boost/thread/win32/thread_primitives.hpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -53,6 +53,7 @@
             using ::SleepEx;
             using ::Sleep;
             using ::QueueUserAPC;
+ using ::GetTickCount;
         }
     }
 }
@@ -120,6 +121,8 @@
                 typedef void (__stdcall *queue_user_apc_callback_function)(ulong_ptr);
                 __declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr);
 
+ __declspec(dllimport) unsigned long __stdcall GetTickCount();
+
 # ifndef UNDER_CE
                 __declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
                 __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();

Modified: branches/release/libs/thread/build/Jamfile.v2
==============================================================================
--- branches/release/libs/thread/build/Jamfile.v2 (original)
+++ branches/release/libs/thread/build/Jamfile.v2 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -157,6 +157,7 @@
 rule requirements ( properties * )
 {
     local result ;
+
     if <threadapi>pthread in $(properties)
     {
         result += <define>BOOST_THREAD_POSIX ;
@@ -201,5 +202,7 @@
     : thread_sources
     : <conditional>@requirements
     :
- : <conditional>@usage-requirements
+ : <link>shared:<define>BOOST_THREAD_USE_DLL=1
+ <link>static:<define>BOOST_THREAD_USE_LIB=1
+ <conditional>@usage-requirements
     ;

Modified: branches/release/libs/thread/src/pthread/once.cpp
==============================================================================
--- branches/release/libs/thread/src/pthread/once.cpp (original)
+++ branches/release/libs/thread/src/pthread/once.cpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -3,6 +3,7 @@
 // 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)
 
+#define __STDC_CONSTANT_MACROS
 #include <boost/thread/once.hpp>
 #include <boost/assert.hpp>
 #include <pthread.h>
@@ -12,9 +13,9 @@
 {
     namespace detail
     {
- boost::uintmax_t once_global_epoch=0;
- pthread_mutex_t once_epoch_mutex=PTHREAD_MUTEX_INITIALIZER;
- pthread_cond_t once_epoch_cv = PTHREAD_COND_INITIALIZER;
+ BOOST_THREAD_DECL boost::uintmax_t once_global_epoch=UINTMAX_C(~0);
+ BOOST_THREAD_DECL pthread_mutex_t once_epoch_mutex=PTHREAD_MUTEX_INITIALIZER;
+ BOOST_THREAD_DECL pthread_cond_t once_epoch_cv = PTHREAD_COND_INITIALIZER;
 
         namespace
         {
@@ -41,11 +42,10 @@
             {
                 data=malloc(sizeof(boost::uintmax_t));
                 BOOST_VERIFY(!pthread_setspecific(epoch_tss_key,data));
- *static_cast<boost::uintmax_t*>(data)=0;
+ *static_cast<boost::uintmax_t*>(data)=UINTMAX_C(~0);
             }
             return *static_cast<boost::uintmax_t*>(data);
         }
-
     }
     
 }

Modified: branches/release/libs/thread/src/pthread/thread.cpp
==============================================================================
--- branches/release/libs/thread/src/pthread/thread.cpp (original)
+++ branches/release/libs/thread/src/pthread/thread.cpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -13,6 +13,14 @@
 #include <boost/thread/locks.hpp>
 #include <boost/thread/once.hpp>
 #include <boost/thread/tss.hpp>
+#ifdef __linux__
+#include <sys/sysinfo.h>
+#elif defined(__APPLE__) || defined(__FreeBSD__)
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#elif defined(__sun)
+#include <unistd.h>
+#endif
 
 #include "timeconv.inl"
 
@@ -188,6 +196,37 @@
         detach();
     }
 
+ thread::thread(detail::thread_move_t<thread> x)
+ {
+ lock_guard<mutex> lock(x->thread_info_mutex);
+ thread_info=x->thread_info;
+ x->thread_info.reset();
+ }
+
+ thread& thread::operator=(detail::thread_move_t<thread> x)
+ {
+ thread new_thread(x);
+ swap(new_thread);
+ return *this;
+ }
+
+ thread::operator detail::thread_move_t<thread>()
+ {
+ return move();
+ }
+
+ detail::thread_move_t<thread> thread::move()
+ {
+ detail::thread_move_t<thread> x(*this);
+ return x;
+ }
+
+ void thread::swap(thread& x)
+ {
+ thread_info.swap(x.thread_info);
+ }
+
+
     bool thread::operator==(const thread& other) const
     {
         return get_id()==other.get_id();
@@ -198,7 +237,7 @@
         return !operator==(other);
     }
 
- boost::shared_ptr<detail::thread_data_base> thread::get_thread_info() const
+ detail::thread_data_ptr thread::get_thread_info() const
     {
         lock_guard<mutex> l(thread_info_mutex);
         return thread_info;
@@ -206,7 +245,7 @@
 
     void thread::join()
     {
- boost::shared_ptr<detail::thread_data_base> const local_thread_info=get_thread_info();
+ detail::thread_data_ptr const local_thread_info=get_thread_info();
         if(local_thread_info)
         {
             bool do_join=false;
@@ -250,7 +289,7 @@
 
     bool thread::timed_join(system_time const& wait_until)
     {
- boost::shared_ptr<detail::thread_data_base> const local_thread_info=get_thread_info();
+ detail::thread_data_ptr const local_thread_info=get_thread_info();
         if(local_thread_info)
         {
             bool do_join=false;
@@ -304,7 +343,7 @@
 
     void thread::detach()
     {
- boost::shared_ptr<detail::thread_data_base> local_thread_info;
+ detail::thread_data_ptr local_thread_info;
         {
             lock_guard<mutex> l1(thread_info_mutex);
             thread_info.swap(local_thread_info);
@@ -377,15 +416,28 @@
 
     unsigned thread::hardware_concurrency()
     {
- return 1;
+#if defined(PTW32_VERSION) || defined(__hpux)
+ return pthread_num_processors_np();
+#elif defined(__linux__)
+ return get_nprocs();
+#elif defined(__APPLE__) || defined(__FreeBSD__)
+ int count;
+ size_t size=sizeof(count);
+ return sysctlbyname("hw.ncpu",&count,&size,NULL,0)?0:count;
+#elif defined(__sun)
+ int const count=sysconf(_SC_NPROCESSORS_ONLN);
+ return (count>0)?count:0;
+#else
+ return 0;
+#endif
     }
 
     thread::id thread::get_id() const
     {
- boost::shared_ptr<detail::thread_data_base> local_thread_info=get_thread_info();
+ detail::thread_data_ptr const local_thread_info=get_thread_info();
         if(local_thread_info)
         {
- return id(local_thread_info->thread_handle);
+ return id(local_thread_info);
         }
         else
         {
@@ -395,7 +447,7 @@
 
     void thread::interrupt()
     {
- boost::shared_ptr<detail::thread_data_base> local_thread_info=get_thread_info();
+ detail::thread_data_ptr const local_thread_info=get_thread_info();
         if(local_thread_info)
         {
             lock_guard<mutex> lk(local_thread_info->data_mutex);
@@ -409,7 +461,7 @@
 
     bool thread::interruption_requested() const
     {
- boost::shared_ptr<detail::thread_data_base> local_thread_info=get_thread_info();
+ detail::thread_data_ptr const local_thread_info=get_thread_info();
         if(local_thread_info)
         {
             lock_guard<mutex> lk(local_thread_info->data_mutex);
@@ -424,6 +476,12 @@
 
     namespace this_thread
     {
+ thread::id get_id()
+ {
+ boost::detail::thread_data_base* const thread_info=get_or_make_current_thread_data();
+ return thread::id(thread_info?thread_info->shared_from_this():detail::thread_data_ptr());
+ }
+
         void interruption_point()
         {
             boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data();

Modified: branches/release/libs/thread/src/win32/thread.cpp
==============================================================================
--- branches/release/libs/thread/src/win32/thread.cpp (original)
+++ branches/release/libs/thread/src/win32/thread.cpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -4,6 +4,9 @@
 // (C) Copyright 2007 Anthony Williams
 // (C) Copyright 2007 David Deakins
 
+#define _WIN32_WINNT 0x400
+#define WINVER 0x400
+
 #include <boost/thread/thread.hpp>
 #include <algorithm>
 #include <windows.h>
@@ -15,6 +18,7 @@
 #include <boost/thread/tss.hpp>
 #include <boost/assert.hpp>
 #include <boost/thread/detail/tss_hooks.hpp>
+#include <boost/date_time/posix_time/conversion.hpp>
 
 namespace boost
 {
@@ -63,11 +67,11 @@
         typedef void* uintptr_t;
 
         inline uintptr_t const _beginthreadex(void* security, unsigned stack_size, unsigned (__stdcall* start_address)(void*),
- void* arglist, unsigned initflag, unsigned* thrdaddr)
+ void* arglist, unsigned initflag, unsigned* thrdaddr)
         {
             DWORD threadID;
             HANDLE hthread=CreateThread(static_cast<LPSECURITY_ATTRIBUTES>(security),stack_size,ThreadProxy,
- new ThreadProxyData(start_address,arglist),initflag,&threadID);
+ new ThreadProxyData(start_address,arglist),initflag,&threadID);
             if (hthread!=0)
                 *thrdaddr=threadID;
             return reinterpret_cast<uintptr_t const>(hthread);
@@ -240,30 +244,28 @@
         detach();
     }
     
- thread::thread(boost::move_t<thread> x)
+ thread::thread(detail::thread_move_t<thread> x)
     {
- {
- boost::mutex::scoped_lock l(x->thread_info_mutex);
- thread_info=x->thread_info;
- }
- x->release_handle();
+ lock_guard<mutex> lock(x->thread_info_mutex);
+ thread_info=x->thread_info;
+ x->thread_info=0;
     }
     
- thread& thread::operator=(boost::move_t<thread> x)
+ thread& thread::operator=(detail::thread_move_t<thread> x)
     {
         thread new_thread(x);
         swap(new_thread);
         return *this;
     }
         
- thread::operator boost::move_t<thread>()
+ thread::operator detail::thread_move_t<thread>()
     {
         return move();
     }
 
- boost::move_t<thread> thread::move()
+ detail::thread_move_t<thread> thread::move()
     {
- boost::move_t<thread> x(*this);
+ detail::thread_move_t<thread> x(*this);
         return x;
     }
 
@@ -287,7 +289,7 @@
         detail::thread_data_ptr local_thread_info=get_thread_info();
         if(local_thread_info)
         {
- this_thread::interruptible_wait(local_thread_info->thread_handle,detail::win32::infinite);
+ this_thread::interruptible_wait(local_thread_info->thread_handle,detail::timeout::sentinel());
             release_handle();
         }
     }
@@ -313,7 +315,7 @@
 
     void thread::release_handle()
     {
- boost::mutex::scoped_lock l1(thread_info_mutex);
+ lock_guard<mutex> l1(thread_info_mutex);
         thread_info=0;
     }
     
@@ -353,13 +355,57 @@
 
     namespace this_thread
     {
- bool interruptible_wait(detail::win32::handle handle_to_wait_for,unsigned long milliseconds)
+ namespace
+ {
+ LARGE_INTEGER get_due_time(detail::timeout const& target_time)
+ {
+ LARGE_INTEGER due_time={0};
+ if(target_time.relative)
+ {
+ unsigned long const elapsed_milliseconds=GetTickCount()-target_time.start;
+ LONGLONG const remaining_milliseconds=(target_time.milliseconds-elapsed_milliseconds);
+ LONGLONG const hundred_nanoseconds_in_one_millisecond=10000;
+
+ if(remaining_milliseconds>0)
+ {
+ due_time.QuadPart=-(remaining_milliseconds*hundred_nanoseconds_in_one_millisecond);
+ }
+ }
+ else
+ {
+ SYSTEMTIME target_system_time={0};
+ target_system_time.wYear=target_time.abs_time.date().year();
+ target_system_time.wMonth=target_time.abs_time.date().month();
+ target_system_time.wDay=target_time.abs_time.date().day();
+ target_system_time.wHour=(WORD)target_time.abs_time.time_of_day().hours();
+ target_system_time.wMinute=(WORD)target_time.abs_time.time_of_day().minutes();
+ target_system_time.wSecond=(WORD)target_time.abs_time.time_of_day().seconds();
+
+ if(!SystemTimeToFileTime(&target_system_time,((FILETIME*)&due_time)))
+ {
+ due_time.QuadPart=0;
+ }
+ else
+ {
+ long const hundred_nanoseconds_in_one_second=10000000;
+ due_time.QuadPart+=target_time.abs_time.time_of_day().fractional_seconds()*(hundred_nanoseconds_in_one_second/target_time.abs_time.time_of_day().ticks_per_second());
+ }
+ }
+ return due_time;
+ }
+ }
+
+
+ bool interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time)
         {
- detail::win32::handle handles[2]={0};
+ detail::win32::handle handles[3]={0};
             unsigned handle_count=0;
+ unsigned wait_handle_index=~0U;
             unsigned interruption_index=~0U;
+ unsigned timeout_index=~0U;
             if(handle_to_wait_for!=detail::win32::invalid_handle_value)
             {
+ wait_handle_index=handle_count;
                 handles[handle_count++]=handle_to_wait_for;
             }
             if(get_current_thread_data() && get_current_thread_data()->interruption_enabled)
@@ -367,24 +413,79 @@
                 interruption_index=handle_count;
                 handles[handle_count++]=get_current_thread_data()->interruption_handle;
             }
-
- if(handle_count)
+
+ detail::win32::handle_manager timer_handle;
+
+#ifndef UNDER_CE
+ unsigned const min_timer_wait_period=20;
+
+ if(!target_time.is_sentinel())
             {
- unsigned long const notified_index=detail::win32::WaitForMultipleObjects(handle_count,handles,false,milliseconds);
- if((handle_to_wait_for!=detail::win32::invalid_handle_value) && !notified_index)
+ detail::timeout::remaining_time const time_left=target_time.remaining_milliseconds();
+ if(time_left.milliseconds > min_timer_wait_period)
                 {
- return true;
+ // for a long-enough timeout, use a waitable timer (which tracks clock changes)
+ timer_handle=CreateWaitableTimer(NULL,false,NULL);
+ if(timer_handle!=0)
+ {
+ LARGE_INTEGER due_time=get_due_time(target_time);
+
+ bool const set_time_succeeded=SetWaitableTimer(timer_handle,&due_time,0,0,0,false)!=0;
+ if(set_time_succeeded)
+ {
+ timeout_index=handle_count;
+ handles[handle_count++]=timer_handle;
+ }
+ }
                 }
- else if(notified_index==interruption_index)
+ else if(!target_time.relative)
                 {
- detail::win32::ResetEvent(get_current_thread_data()->interruption_handle);
- throw thread_interrupted();
+ // convert short absolute-time timeouts into relative ones, so we don't race against clock changes
+ target_time=detail::timeout(time_left.milliseconds);
                 }
             }
- else
+#endif
+
+ bool const using_timer=timeout_index!=~0u;
+ detail::timeout::remaining_time time_left(0);
+
+ do
             {
- detail::win32::Sleep(milliseconds);
+ if(!using_timer)
+ {
+ time_left=target_time.remaining_milliseconds();
+ }
+
+ if(handle_count)
+ {
+ unsigned long const notified_index=detail::win32::WaitForMultipleObjects(handle_count,handles,false,using_timer?INFINITE:time_left.milliseconds);
+ if(notified_index<handle_count)
+ {
+ if(notified_index==wait_handle_index)
+ {
+ return true;
+ }
+ else if(notified_index==interruption_index)
+ {
+ detail::win32::ResetEvent(get_current_thread_data()->interruption_handle);
+ throw thread_interrupted();
+ }
+ else if(notified_index==timeout_index)
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ detail::win32::Sleep(time_left.milliseconds);
+ }
+ if(target_time.relative)
+ {
+ target_time.milliseconds-=detail::timeout::max_non_infinite_wait;
+ }
             }
+ while(time_left.more);
             return false;
         }
 
@@ -494,7 +595,7 @@
             tss_cleanup_implemented(); // if anyone uses TSS, we need the cleanup linked in
             if(tss_data_node* const current_node=find_tss_data(key))
             {
- if(cleanup_existing && current_node->func)
+ if(cleanup_existing && current_node->func.get())
                 {
                     (*current_node->func)(current_node->value);
                 }

Modified: branches/release/libs/thread/src/win32/tss_pe.cpp
==============================================================================
--- branches/release/libs/thread/src/win32/tss_pe.cpp (original)
+++ branches/release/libs/thread/src/win32/tss_pe.cpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -230,13 +230,10 @@
 
         void NTAPI on_tls_callback(HINSTANCE h, DWORD dwReason, PVOID pv)
         {
- OutputDebugString("on_tls_callback\n");
-
             switch (dwReason)
             {
                 case DLL_THREAD_DETACH:
                 {
- OutputDebugString("on_tls_callback: thread_exit\n");
                     on_thread_exit();
                     break;
                 }

Modified: branches/release/libs/thread/test/Jamfile.v2
==============================================================================
--- branches/release/libs/thread/test/Jamfile.v2 (original)
+++ branches/release/libs/thread/test/Jamfile.v2 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -1,4 +1,5 @@
 # (C) Copyright William E. Kempf 2001.
+# (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)
 #
@@ -34,13 +35,21 @@
 {
     test-suite "threads"
         : [ thread-run test_thread.cpp ]
+ [ thread-run test_thread_id.cpp ]
+ [ thread-run test_hardware_concurrency.cpp ]
+ [ thread-run test_thread_move.cpp ]
+ [ thread-run test_move_function.cpp ]
           [ thread-run test_mutex.cpp ]
+ [ thread-run test_condition_notify_one.cpp ]
+ [ thread-run test_condition_timed_wait_times_out.cpp ]
+ [ thread-run test_condition_notify_all.cpp ]
           [ thread-run test_condition.cpp ]
           [ thread-run test_tss.cpp ]
           [ thread-run test_once.cpp ]
           [ thread-run test_xtime.cpp ]
           [ thread-run test_barrier.cpp ]
           [ thread-run test_shared_mutex.cpp ]
+ [ thread-run test_shared_mutex_part_2.cpp ]
           [ thread-run test_lock_concept.cpp ]
     ;
 }

Modified: branches/release/libs/thread/test/test_barrier.cpp
==============================================================================
--- branches/release/libs/thread/test/test_barrier.cpp (original)
+++ branches/release/libs/thread/test/test_barrier.cpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -52,7 +52,7 @@
         throw;
     }
     
- BOOST_CHECK(global_parameter == 5);
+ BOOST_CHECK_EQUAL(global_parameter,5);
 }
 
 boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])

Modified: branches/release/libs/thread/test/test_condition.cpp
==============================================================================
--- branches/release/libs/thread/test/test_condition.cpp (original)
+++ branches/release/libs/thread/test/test_condition.cpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -1,5 +1,6 @@
 // Copyright (C) 2001-2003
 // William E. Kempf
+// Copyright (C) 2007 Anthony Williams
 //
 // Distributed under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -19,7 +20,7 @@
     condition_test_data() : notified(0), awoken(0) { }
 
     boost::mutex mutex;
- boost::condition condition;
+ boost::condition_variable condition;
     int notified;
     int awoken;
 };
@@ -82,66 +83,15 @@
     BOOST_CHECK_EQUAL(data->notified, 4);
     data->awoken++;
     data->condition.notify_one();
-}
-
-void do_test_condition_notify_one()
-{
- condition_test_data data;
-
- boost::thread thread(bind(&condition_test_thread, &data));
-
- {
- boost::mutex::scoped_lock lock(data.mutex);
- BOOST_CHECK(lock ? true : false);
- data.notified++;
- data.condition.notify_one();
- }
-
- thread.join();
- BOOST_CHECK_EQUAL(data.awoken, 1);
-}
-
-void test_condition_notify_one()
-{
- timed_test(&do_test_condition_notify_one, 100, execution_monitor::use_mutex);
-}
-
-void do_test_condition_notify_all()
-{
- const int NUMTHREADS = 5;
- boost::thread_group threads;
- condition_test_data data;
-
- try
- {
- for (int i = 0; i < NUMTHREADS; ++i)
- threads.create_thread(bind(&condition_test_thread, &data));
-
- {
- boost::mutex::scoped_lock lock(data.mutex);
- BOOST_CHECK(lock ? true : false);
- data.notified++;
- data.condition.notify_all();
- }
-
- threads.join_all();
- }
- catch(...)
- {
- threads.interrupt_all();
- threads.join_all();
- throw;
- }
 
- BOOST_CHECK_EQUAL(data.awoken, NUMTHREADS);
-}
-
-void test_condition_notify_all()
-{
- // We should have already tested notify_one here, so
- // a timed test with the default execution_monitor::use_condition
- // should be OK, and gives the fastest performance
- timed_test(&do_test_condition_notify_all, 100);
+ // Test predicate timed_wait with relative timeout
+ cond_predicate pred_rel(data->notified, 5);
+ BOOST_CHECK(data->condition.timed_wait(lock, boost::posix_time::seconds(10), pred_rel));
+ BOOST_CHECK(lock ? true : false);
+ BOOST_CHECK(pred_rel());
+ BOOST_CHECK_EQUAL(data->notified, 5);
+ data->awoken++;
+ data->condition.notify_one();
 }
 
 void do_test_condition_waits()
@@ -185,10 +135,19 @@
             data.condition.wait(lock);
         BOOST_CHECK(lock ? true : false);
         BOOST_CHECK_EQUAL(data.awoken, 4);
+
+
+ boost::thread::sleep(delay(1));
+ data.notified++;
+ data.condition.notify_one();
+ while (data.awoken != 5)
+ data.condition.wait(lock);
+ BOOST_CHECK(lock ? true : false);
+ BOOST_CHECK_EQUAL(data.awoken, 5);
     }
 
     thread.join();
- BOOST_CHECK_EQUAL(data.awoken, 4);
+ BOOST_CHECK_EQUAL(data.awoken, 5);
 }
 
 void test_condition_waits()
@@ -216,14 +175,11 @@
     timed_test(&do_test_condition_wait_is_a_interruption_point, 1);
 }
 
-
 boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
 {
     boost::unit_test_framework::test_suite* test =
         BOOST_TEST_SUITE("Boost.Threads: condition test suite");
 
- test->add(BOOST_TEST_CASE(&test_condition_notify_one));
- test->add(BOOST_TEST_CASE(&test_condition_notify_all));
     test->add(BOOST_TEST_CASE(&test_condition_waits));
     test->add(BOOST_TEST_CASE(&test_condition_wait_is_a_interruption_point));
 

Modified: branches/release/libs/thread/test/test_mutex.cpp
==============================================================================
--- branches/release/libs/thread/test/test_mutex.cpp (original)
+++ branches/release/libs/thread/test/test_mutex.cpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -102,6 +102,11 @@
     typedef M mutex_type;
     typedef typename M::scoped_timed_lock timed_lock_type;
 
+ static bool fake_predicate()
+ {
+ return false;
+ }
+
     void operator()()
     {
         mutex_type mutex;
@@ -123,14 +128,17 @@
         BOOST_CHECK(lock ? true : false);
 
         // Construct and initialize an xtime for a fast time out.
- boost::xtime xt = delay(0, 100);
+ boost::system_time timeout = boost::get_system_time()+boost::posix_time::milliseconds(100);
 
         // Test the lock and the mutex with condition variables.
         // No one is going to notify this condition variable. We expect to
         // time out.
- BOOST_CHECK(!condition.timed_wait(lock, xt));
+ BOOST_CHECK(!condition.timed_wait(lock, timeout, fake_predicate));
         BOOST_CHECK(lock ? true : false);
- BOOST_CHECK(in_range(xt));
+
+ boost::system_time now=boost::get_system_time();
+ boost::posix_time::milliseconds const timeout_resolution(20);
+ BOOST_CHECK((timeout-timeout_resolution)<now);
 
         // Test the lock, unlock and timedlock methods.
         lock.unlock();

Modified: branches/release/libs/thread/test/test_once.cpp
==============================================================================
--- branches/release/libs/thread/test/test_once.cpp (original)
+++ branches/release/libs/thread/test/test_once.cpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -19,6 +19,7 @@
     ++var_to_init;
 }
 
+
 void call_once_thread()
 {
     unsigned const loop_count=100;

Modified: branches/release/libs/thread/test/test_shared_mutex.cpp
==============================================================================
--- branches/release/libs/thread/test/test_shared_mutex.cpp (original)
+++ branches/release/libs/thread/test/test_shared_mutex.cpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -5,13 +5,9 @@
 
 #include <boost/test/unit_test.hpp>
 #include <boost/thread/thread.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/condition_variable.hpp>
-#include <boost/thread/shared_mutex.hpp>
 #include <boost/thread/xtime.hpp>
 #include "util.inl"
-#include <iostream>
-#include <boost/date_time/posix_time/posix_time_io.hpp>
+#include "shared_mutex_locking_thread.hpp"
 
 #define CHECK_LOCKED_VALUE_EQUAL(mutex_name,value,expected_value) \
     { \
@@ -19,65 +15,6 @@
         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::condition_variable& unblocked_condition;
- boost::mutex& finish_mutex;
- public:
- locking_thread(boost::shared_mutex& rw_mutex_,
- unsigned& unblocked_count_,
- boost::mutex& unblocked_count_mutex_,
- boost::condition_variable& unblocked_condition_,
- boost::mutex& finish_mutex_,
- unsigned& simultaneous_running_count_,
- unsigned& max_simultaneous_running_):
- rw_mutex(rw_mutex_),
- unblocked_count(unblocked_count_),
- unblocked_condition(unblocked_condition_),
- simultaneous_running_count(simultaneous_running_count_),
- max_simultaneous_running(max_simultaneous_running_),
- unblocked_count_mutex(unblocked_count_mutex_),
- finish_mutex(finish_mutex_)
- {}
-
- 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;
- unblocked_condition.notify_one();
- ++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;
@@ -328,250 +265,11 @@
         throw;
     }
 
-
     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,1u);
 }
 
-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::condition_variable unblocked_condition;
- boost::mutex finish_mutex;
- boost::mutex::scoped_lock finish_lock(finish_mutex);
-
- try
- {
- 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,unblocked_condition,
- 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();
- }
- catch(...)
- {
- pool.interrupt_all();
- pool.join_all();
- throw;
- }
-
- CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,number_of_threads);
- CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,1u);
-}
-
-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::condition_variable unblocked_condition;
- boost::mutex finish_mutex;
- boost::mutex::scoped_lock finish_lock(finish_mutex);
-
- unsigned const reader_count=100;
-
- try
- {
- 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,unblocked_condition,
- finish_mutex,simultaneous_running_count,max_simultaneous_running));
- }
- boost::thread::sleep(delay(1));
- pool.create_thread(locking_thread<boost::upgrade_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
- finish_mutex,simultaneous_running_count,max_simultaneous_running));
- {
- boost::mutex::scoped_lock lk(unblocked_count_mutex);
- while(unblocked_count<(reader_count+1))
- {
- unblocked_condition.wait(lk);
- }
- }
- CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+1);
-
- finish_lock.unlock();
- pool.join_all();
- }
- catch(...)
- {
- pool.interrupt_all();
- pool.join_all();
- throw;
- }
-
-
- 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,1u);
-
- 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,1u);
-
- 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,1u);
-
- boost::system_time const start=boost::get_system_time();
- boost::system_time const timeout=start+boost::posix_time::milliseconds(2000);
- bool const timed_lock_succeeded=rw_mutex.timed_lock_shared(timeout);
- BOOST_CHECK(in_range(boost::get_xtime(timeout),1));
- 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 =
@@ -582,12 +280,6 @@
     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;
 }

Modified: branches/release/libs/thread/test/test_tss.cpp
==============================================================================
--- branches/release/libs/thread/test/test_tss.cpp (original)
+++ branches/release/libs/thread/test/test_tss.cpp 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -1,5 +1,6 @@
 // Copyright (C) 2001-2003
 // William E. Kempf
+// Copyright (C) 2007 Anthony Williams
 //
 // Distributed under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -73,7 +74,7 @@
 
     native_thread_t create_native_thread(void)
     {
- return CreateThread(
+ native_thread_t const res=CreateThread(
             0, //security attributes (0 = not inheritable)
             0, //stack size (0 = default)
             &test_tss_thread_native, //function to execute
@@ -81,6 +82,8 @@
             0, //creation flags (0 = run immediately)
             0 //thread id (0 = thread id not returned)
             );
+ BOOST_CHECK(res!=0);
+ return res;
     }
 
     void join_native_thread(native_thread_t thread)
@@ -154,19 +157,10 @@
     tss_total = 0;
 
     native_thread_t thread1 = create_native_thread();
- BOOST_CHECK(thread1 != 0);
-
     native_thread_t thread2 = create_native_thread();
- BOOST_CHECK(thread2 != 0);
-
     native_thread_t thread3 = create_native_thread();
- BOOST_CHECK(thread3 != 0);
-
     native_thread_t thread4 = create_native_thread();
- BOOST_CHECK(thread3 != 0);
-
     native_thread_t thread5 = create_native_thread();
- BOOST_CHECK(thread3 != 0);
 
     join_native_thread(thread5);
     join_native_thread(thread4);

Modified: branches/release/libs/thread/test/util.inl
==============================================================================
--- branches/release/libs/thread/test/util.inl (original)
+++ branches/release/libs/thread/test/util.inl 2007-12-21 06:51:05 EST (Fri, 21 Dec 2007)
@@ -1,5 +1,6 @@
 // Copyright (C) 2001-2003
 // William E. Kempf
+// Copyright (C) 2007 Anthony Williams
 //
 // Distributed under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -154,6 +155,26 @@
 {
     return thread_binder<F, T>(func, param);
 }
+
+template <typename R, typename T>
+class thread_member_binder
+{
+public:
+ thread_member_binder(R (T::*func)(), T& param)
+ : func(func), param(param) { }
+ void operator()() const { (param.*func)(); }
+
+private:
+ R (T::*func)();
+ T& param;
+};
+
+
+template <typename R, typename T>
+thread_member_binder<R, T> bind(R (T::*func)(), T& param)
+{
+ return thread_member_binder<R, T>(func, param);
+}
 } // namespace
 
 #endif


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk