Boost logo

Boost-Commit :

From: anthony_at_[hidden]
Date: 2008-06-18 09:01:13


Author: anthonyw
Date: 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
New Revision: 46474
URL: http://svn.boost.org/trac/boost/changeset/46474

Log:
Merge of new boost.thread code along with required changes from boost.bind
Added:
   branches/release/boost/bind/bind_mf2_cc.hpp
      - copied unchanged from r46473, /trunk/boost/bind/bind_mf2_cc.hpp
   branches/release/boost/thread/detail/thread.hpp
      - copied, changed from r46368, /trunk/boost/thread/detail/thread.hpp
   branches/release/boost/thread/detail/thread_heap_alloc.hpp
      - copied unchanged from r46368, /trunk/boost/thread/detail/thread_heap_alloc.hpp
   branches/release/boost/thread/pthread/thread_heap_alloc.hpp
      - copied unchanged from r46368, /trunk/boost/thread/pthread/thread_heap_alloc.hpp
   branches/release/boost/thread/tss.hpp
      - copied unchanged from r46368, /trunk/boost/thread/tss.hpp
   branches/release/boost/thread/win32/thread_data.hpp
      - copied unchanged from r46368, /trunk/boost/thread/win32/thread_data.hpp
   branches/release/libs/bind/test/bind_and_or_test.cpp
      - copied unchanged from r46473, /trunk/libs/bind/test/bind_and_or_test.cpp
   branches/release/libs/bind/test/bind_fn2_test.cpp
      - copied unchanged from r46473, /trunk/libs/bind/test/bind_fn2_test.cpp
   branches/release/libs/bind/test/bind_fnobj2_test.cpp
      - copied unchanged from r46473, /trunk/libs/bind/test/bind_fnobj2_test.cpp
   branches/release/libs/bind/test/bind_mf2_test.cpp
      - copied unchanged from r46473, /trunk/libs/bind/test/bind_mf2_test.cpp
   branches/release/libs/bind/test/ref_fn_test.cpp
      - copied unchanged from r46473, /trunk/libs/bind/test/ref_fn_test.cpp
   branches/release/libs/thread/doc/time.qbk
      - copied unchanged from r46368, /trunk/libs/thread/doc/time.qbk
   branches/release/libs/thread/test/no_implicit_assign_from_lvalue_thread.cpp
      - copied unchanged from r46368, /trunk/libs/thread/test/no_implicit_assign_from_lvalue_thread.cpp
   branches/release/libs/thread/test/no_implicit_move_from_lvalue_thread.cpp
      - copied unchanged from r46368, /trunk/libs/thread/test/no_implicit_move_from_lvalue_thread.cpp
   branches/release/libs/thread/test/test_generic_locks.cpp
      - copied unchanged from r46368, /trunk/libs/thread/test/test_generic_locks.cpp
   branches/release/libs/thread/test/test_shared_mutex_timed_locks.cpp
      - copied unchanged from r46368, /trunk/libs/thread/test/test_shared_mutex_timed_locks.cpp
   branches/release/libs/thread/test/test_thread_launching.cpp
      - copied unchanged from r46368, /trunk/libs/thread/test/test_thread_launching.cpp
   branches/release/libs/thread/test/test_thread_mf.cpp
      - copied unchanged from r46368, /trunk/libs/thread/test/test_thread_mf.cpp
Removed:
   branches/release/boost/thread/pthread/thread.hpp
   branches/release/boost/thread/pthread/tss.hpp
   branches/release/boost/thread/win32/thread.hpp
   branches/release/boost/thread/win32/tss.hpp
Text files modified:
   branches/release/boost/bind.hpp | 30 +
   branches/release/boost/thread.hpp | 8
   branches/release/boost/thread/barrier.hpp | 6
   branches/release/boost/thread/detail/move.hpp | 27 +
   branches/release/boost/thread/detail/thread.hpp | 4
   branches/release/boost/thread/detail/tss_hooks.hpp | 6
   branches/release/boost/thread/exceptions.hpp | 12
   branches/release/boost/thread/locks.hpp | 628 +++++++++++++++++++++++++++++++++++++--
   branches/release/boost/thread/once.hpp | 4
   branches/release/boost/thread/pthread/condition_variable.hpp | 23 -
   branches/release/boost/thread/pthread/condition_variable_fwd.hpp | 27 +
   branches/release/boost/thread/pthread/mutex.hpp | 22
   branches/release/boost/thread/pthread/once.hpp | 9
   branches/release/boost/thread/pthread/pthread_mutex_scoped_lock.hpp | 6
   branches/release/boost/thread/pthread/recursive_mutex.hpp | 25 +
   branches/release/boost/thread/pthread/shared_mutex.hpp | 169 +++-------
   branches/release/boost/thread/pthread/thread_data.hpp | 29 +
   branches/release/boost/thread/pthread/timespec.hpp | 14
   branches/release/boost/thread/thread.hpp | 9
   branches/release/boost/thread/thread_time.hpp | 4
   branches/release/boost/thread/win32/basic_recursive_mutex.hpp | 6
   branches/release/boost/thread/win32/basic_timed_mutex.hpp | 71 ++--
   branches/release/boost/thread/win32/condition_variable.hpp | 304 +++++++++++--------
   branches/release/boost/thread/win32/interlocked_read.hpp | 9
   branches/release/boost/thread/win32/mutex.hpp | 8
   branches/release/boost/thread/win32/once.hpp | 4
   branches/release/boost/thread/win32/recursive_mutex.hpp | 7
   branches/release/boost/thread/win32/shared_mutex.hpp | 32 +
   branches/release/boost/thread/win32/thread_heap_alloc.hpp | 243 ++++++++++++++
   branches/release/boost/thread/win32/thread_primitives.hpp | 116 +++++++
   branches/release/boost/thread/xtime.hpp | 8
   branches/release/boost/utility/addressof.hpp | 39 +-
   branches/release/libs/bind/bind.html | 99 ++++-
   branches/release/libs/bind/test/Jamfile.v2 | 5
   branches/release/libs/bind/test/bind_lookup_problem_test.cpp | 2
   branches/release/libs/thread/doc/changes.qbk | 7
   branches/release/libs/thread/doc/mutex_concepts.qbk | 30 +
   branches/release/libs/thread/doc/mutexes.qbk | 77 ++++
   branches/release/libs/thread/doc/thread.qbk | 2
   branches/release/libs/thread/doc/thread_ref.qbk | 77 ++++
   branches/release/libs/thread/example/condition.cpp | 12
   branches/release/libs/thread/src/pthread/thread.cpp | 299 +++++++++----------
   branches/release/libs/thread/src/tss_null.cpp | 2
   branches/release/libs/thread/src/win32/thread.cpp | 86 +----
   branches/release/libs/thread/test/Jamfile.v2 | 20
   branches/release/libs/thread/test/shared_mutex_locking_thread.hpp | 62 +++
   branches/release/libs/thread/test/test_condition_notify_all.cpp | 42 ++
   branches/release/libs/thread/test/test_condition_notify_one.cpp | 42 ++
   branches/release/libs/thread/test/test_lock_concept.cpp | 106 ++++++
   branches/release/libs/thread/test/test_move_function.cpp | 74 ++++
   branches/release/libs/thread/test/test_shared_mutex_part_2.cpp | 96 ------
   branches/release/libs/thread/test/test_thread.cpp | 18 +
   branches/release/libs/thread/test/test_tss.cpp | 48 +++
   53 files changed, 2339 insertions(+), 776 deletions(-)

Modified: branches/release/boost/bind.hpp
==============================================================================
--- branches/release/boost/bind.hpp (original)
+++ branches/release/boost/bind.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -248,6 +248,9 @@
     }
 };
 
+struct logical_and;
+struct logical_or;
+
 template< class A1, class A2 > class list2: private storage2< A1, A2 >
 {
 private:
@@ -294,6 +297,26 @@
         unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);
     }
 
+ template<class A> bool operator()( type<bool>, logical_and & /*f*/, A & a, int )
+ {
+ return a[ base_type::a1_ ] && a[ base_type::a2_ ];
+ }
+
+ template<class A> bool operator()( type<bool>, logical_and const & /*f*/, A & a, int ) const
+ {
+ return a[ base_type::a1_ ] && a[ base_type::a2_ ];
+ }
+
+ template<class A> bool operator()( type<bool>, logical_or & /*f*/, A & a, int )
+ {
+ return a[ base_type::a1_ ] || a[ base_type::a2_ ];
+ }
+
+ template<class A> bool operator()( type<bool>, logical_or const & /*f*/, A & a, int ) const
+ {
+ return a[ base_type::a1_ ] || a[ base_type::a2_ ];
+ }
+
     template<class V> void accept(V & v) const
     {
         base_type::accept(v);
@@ -1158,6 +1181,9 @@
 BOOST_BIND_OPERATOR( >, greater )
 BOOST_BIND_OPERATOR( >=, greater_equal )
 
+BOOST_BIND_OPERATOR( &&, logical_and )
+BOOST_BIND_OPERATOR( ||, logical_or )
+
 #undef BOOST_BIND_OPERATOR
 
 #if defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3)
@@ -1542,6 +1568,7 @@
 #define BOOST_BIND_MF_CC
 
 #include <boost/bind/bind_mf_cc.hpp>
+#include <boost/bind/bind_mf2_cc.hpp>
 
 #undef BOOST_BIND_MF_NAME
 #undef BOOST_BIND_MF_CC
@@ -1552,6 +1579,7 @@
 #define BOOST_BIND_MF_CC __cdecl
 
 #include <boost/bind/bind_mf_cc.hpp>
+#include <boost/bind/bind_mf2_cc.hpp>
 
 #undef BOOST_BIND_MF_NAME
 #undef BOOST_BIND_MF_CC
@@ -1564,6 +1592,7 @@
 #define BOOST_BIND_MF_CC __stdcall
 
 #include <boost/bind/bind_mf_cc.hpp>
+#include <boost/bind/bind_mf2_cc.hpp>
 
 #undef BOOST_BIND_MF_NAME
 #undef BOOST_BIND_MF_CC
@@ -1576,6 +1605,7 @@
 #define BOOST_BIND_MF_CC __fastcall
 
 #include <boost/bind/bind_mf_cc.hpp>
+#include <boost/bind/bind_mf2_cc.hpp>
 
 #undef BOOST_BIND_MF_NAME
 #undef BOOST_BIND_MF_CC

Modified: branches/release/boost/thread.hpp
==============================================================================
--- branches/release/boost/thread.hpp (original)
+++ branches/release/boost/thread.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -1,5 +1,6 @@
 // Copyright (C) 2001-2003
 // William E. Kempf
+// (C) Copyright 2008 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)
@@ -10,12 +11,15 @@
 #define BOOST_THREAD_WEK01082003_HPP
 
 #include <boost/thread/thread.hpp>
-#include <boost/thread/condition.hpp>
+#include <boost/thread/condition_variable.hpp>
 #include <boost/thread/exceptions.hpp>
 #include <boost/thread/mutex.hpp>
 #include <boost/thread/once.hpp>
 #include <boost/thread/recursive_mutex.hpp>
 #include <boost/thread/tss.hpp>
-#include <boost/thread/xtime.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/barrier.hpp>
 
 #endif

Modified: branches/release/boost/thread/barrier.hpp
==============================================================================
--- branches/release/boost/thread/barrier.hpp (original)
+++ branches/release/boost/thread/barrier.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -1,6 +1,6 @@
 // Copyright (C) 2002-2003
 // David Moore, William E. Kempf
-// Copyright (C) 2007 Anthony Williams
+// Copyright (C) 2007-8 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)
@@ -15,6 +15,8 @@
 #include <string>
 #include <stdexcept>
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
 
@@ -56,4 +58,6 @@
 
 } // namespace boost
 
+#include <boost/config/abi_suffix.hpp>
+
 #endif

Modified: branches/release/boost/thread/detail/move.hpp
==============================================================================
--- branches/release/boost/thread/detail/move.hpp (original)
+++ branches/release/boost/thread/detail/move.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -1,11 +1,16 @@
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
-// (C) Copyright 2007 Anthony Williams
+// (C) Copyright 2007-8 Anthony Williams
 
 #ifndef BOOST_THREAD_MOVE_HPP
 #define BOOST_THREAD_MOVE_HPP
 
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
     namespace detail
@@ -14,10 +19,15 @@
         struct thread_move_t
         {
             T& t;
- thread_move_t(T& t_):
+ explicit thread_move_t(T& t_):
                 t(t_)
             {}
 
+ T& operator*() const
+ {
+ return t;
+ }
+
             T* operator->() const
             {
                 return &t;
@@ -26,8 +36,21 @@
             void operator=(thread_move_t&);
         };
     }
+
+ template<typename T>
+ typename enable_if<boost::is_convertible<T&,detail::thread_move_t<T> >, detail::thread_move_t<T> >::type move(T& t)
+ {
+ return t;
+ }
+
+ template<typename T>
+ detail::thread_move_t<T> move(detail::thread_move_t<T> t)
+ {
+ return t;
+ }
     
 }
 
+#include <boost/config/abi_suffix.hpp>
 
 #endif

Copied: branches/release/boost/thread/detail/thread.hpp (from r46368, /trunk/boost/thread/detail/thread.hpp)
==============================================================================
--- /trunk/boost/thread/detail/thread.hpp (original)
+++ branches/release/boost/thread/detail/thread.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -163,7 +163,7 @@
         thread& operator=(thread&& other)
         {
             thread_info=other.thread_info;
- other.thread_info.reset();
+ other.thread_info.reset((detail::thread_data_base*)0);
             return *this;
         }
 
@@ -190,7 +190,7 @@
         thread(detail::thread_move_t<thread> x)
         {
             thread_info=x->thread_info;
- x->thread_info.reset();
+ x->thread_info.reset((detail::thread_data_base*)0);
         }
         
         thread& operator=(detail::thread_move_t<thread> x)

Modified: branches/release/boost/thread/detail/tss_hooks.hpp
==============================================================================
--- branches/release/boost/thread/detail/tss_hooks.hpp (original)
+++ branches/release/boost/thread/detail/tss_hooks.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -8,6 +8,8 @@
 
 #include <boost/thread/detail/config.hpp>
 
+#include <boost/config/abi_prefix.hpp>
+
 #if defined(BOOST_HAS_WINTHREADS)
 
     typedef void (__cdecl *thread_exit_handler)(void);
@@ -59,7 +61,7 @@
             //a method for doing so has been discovered.
         //May be omitted; may be called multiple times.
 
- extern "C" BOOST_THREAD_DECL void on_thread_exit(void);
+ extern "C" BOOST_THREAD_DECL void __cdecl on_thread_exit(void);
         //Function to be called just be fore a thread ends
             //in an exe or dll that uses Boost.Threads.
         //Must be called in the context of the thread
@@ -75,4 +77,6 @@
 
 #endif //defined(BOOST_HAS_WINTHREADS)
 
+#include <boost/config/abi_suffix.hpp>
+
 #endif //!defined(BOOST_TLS_HOOKS_HPP)

Modified: branches/release/boost/thread/exceptions.hpp
==============================================================================
--- branches/release/boost/thread/exceptions.hpp (original)
+++ branches/release/boost/thread/exceptions.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -1,6 +1,6 @@
 // Copyright (C) 2001-2003
 // William E. Kempf
-// Copyright (C) 2007 Anthony Williams
+// Copyright (C) 2007-8 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 +19,13 @@
 #include <string>
 #include <stdexcept>
 
-namespace boost {
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+ class BOOST_THREAD_DECL thread_interrupted
+ {};
 
 class BOOST_THREAD_DECL thread_exception : public std::exception
 {
@@ -99,6 +105,8 @@
 
 } // namespace boost
 
+#include <boost/config/abi_suffix.hpp>
+
 #endif // BOOST_THREAD_CONFIG_PDM070801_H
 
 // Change log:

Modified: branches/release/boost/thread/locks.hpp
==============================================================================
--- branches/release/boost/thread/locks.hpp (original)
+++ branches/release/boost/thread/locks.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -8,10 +8,77 @@
 #include <boost/thread/exceptions.hpp>
 #include <boost/thread/detail/move.hpp>
 #include <algorithm>
+#include <iterator>
 #include <boost/thread/thread_time.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/config/abi_prefix.hpp>
 
 namespace boost
 {
+ namespace detail
+ {
+ template<typename T>
+ struct has_member_lock
+ {
+ typedef char true_type;
+ struct false_type
+ {
+ true_type dummy[2];
+ };
+
+ template<typename U>
+ static true_type has_member(U*,void (U::*dummy)()=&U::lock);
+ static false_type has_member(void*);
+
+ BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_lock<T>::has_member((T*)NULL))==sizeof(true_type));
+ };
+
+ template<typename T>
+ struct has_member_unlock
+ {
+ typedef char true_type;
+ struct false_type
+ {
+ true_type dummy[2];
+ };
+
+ template<typename U>
+ static true_type has_member(U*,void (U::*dummy)()=&U::unlock);
+ static false_type has_member(void*);
+
+ BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_unlock<T>::has_member((T*)NULL))==sizeof(true_type));
+ };
+
+ template<typename T>
+ struct has_member_try_lock
+ {
+ typedef char true_type;
+ struct false_type
+ {
+ true_type dummy[2];
+ };
+
+ template<typename U>
+ static true_type has_member(U*,bool (U::*dummy)()=&U::try_lock);
+ static false_type has_member(void*);
+
+ BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_try_lock<T>::has_member((T*)NULL))==sizeof(true_type));
+ };
+
+ }
+
+
+ template<typename T>
+ struct is_mutex_type
+ {
+ BOOST_STATIC_CONSTANT(bool, value = detail::has_member_lock<T>::value &&
+ detail::has_member_unlock<T>::value &&
+ detail::has_member_try_lock<T>::value);
+
+ };
+
+
     struct defer_lock_t
     {};
     struct try_to_lock_t
@@ -62,6 +129,10 @@
         explicit unique_lock(unique_lock&);
         unique_lock& operator=(unique_lock&);
     public:
+ unique_lock():
+ m(0),is_locked(false)
+ {}
+
         explicit unique_lock(Mutex& m_):
             m(&m_),is_locked(false)
         {
@@ -205,15 +276,9 @@
     };
 
     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)
+ void swap(unique_lock<Mutex>& lhs,unique_lock<Mutex>& rhs)
     {
- return x;
+ lhs.swap(rhs);
     }
 
     template<typename Mutex>
@@ -226,6 +291,10 @@
         explicit shared_lock(shared_lock&);
         shared_lock& operator=(shared_lock&);
     public:
+ shared_lock():
+ m(0),is_locked(false)
+ {}
+
         explicit shared_lock(Mutex& m_):
             m(&m_),is_locked(false)
         {
@@ -252,26 +321,29 @@
             m(other->m),is_locked(other->is_locked)
         {
             other->is_locked=false;
+ other->m=0;
         }
 
         shared_lock(detail::thread_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_shared();
             }
+ other->is_locked=false;
+ other->m=0;
         }
 
         shared_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
             m(other->m),is_locked(other->is_locked)
         {
- other->is_locked=false;
             if(is_locked)
             {
                 m->unlock_upgrade_and_lock_shared();
             }
+ other->is_locked=false;
+ other->m=0;
         }
 
         operator detail::thread_move_t<shared_lock<Mutex> >()
@@ -373,19 +445,6 @@
     };
 
     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:
@@ -395,33 +454,42 @@
         explicit upgrade_lock(upgrade_lock&);
         upgrade_lock& operator=(upgrade_lock&);
     public:
+ upgrade_lock():
+ m(0),is_locked(false)
+ {}
+
         explicit upgrade_lock(Mutex& m_):
             m(&m_),is_locked(false)
         {
             lock();
         }
- upgrade_lock(Mutex& m_,bool do_lock):
+ upgrade_lock(Mutex& m_,adopt_lock_t):
+ m(&m_),is_locked(true)
+ {}
+ upgrade_lock(Mutex& m_,defer_lock_t):
+ m(&m_),is_locked(false)
+ {}
+ upgrade_lock(Mutex& m_,try_to_lock_t):
             m(&m_),is_locked(false)
         {
- if(do_lock)
- {
- lock();
- }
+ try_lock();
         }
         upgrade_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
             m(other->m),is_locked(other->is_locked)
         {
             other->is_locked=false;
+ other->m=0;
         }
 
         upgrade_lock(detail::thread_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_upgrade();
             }
+ other->is_locked=false;
+ other->m=0;
         }
 
         operator detail::thread_move_t<upgrade_lock<Mutex> >()
@@ -509,18 +577,6 @@
 
 
     template<typename Mutex>
- inline detail::thread_move_t<upgrade_lock<Mutex> > move(upgrade_lock<Mutex> & x)
- {
- return x.move();
- }
-
- template<typename Mutex>
- 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)
     {
@@ -584,6 +640,496 @@
         }
     };
 
+ namespace detail
+ {
+ template<typename Mutex>
+ class try_lock_wrapper:
+ private unique_lock<Mutex>
+ {
+ typedef unique_lock<Mutex> base;
+ public:
+ try_lock_wrapper()
+ {}
+
+ explicit try_lock_wrapper(Mutex& m):
+ base(m,try_to_lock)
+ {}
+
+ try_lock_wrapper(Mutex& m_,adopt_lock_t):
+ base(m_,adopt_lock)
+ {}
+ try_lock_wrapper(Mutex& m_,defer_lock_t):
+ base(m_,defer_lock)
+ {}
+ try_lock_wrapper(Mutex& m_,try_to_lock_t):
+ base(m_,try_to_lock)
+ {}
+ try_lock_wrapper(detail::thread_move_t<try_lock_wrapper<Mutex> > other):
+ base(detail::thread_move_t<base>(*other))
+ {}
+
+ operator detail::thread_move_t<try_lock_wrapper<Mutex> >()
+ {
+ return move();
+ }
+
+ detail::thread_move_t<try_lock_wrapper<Mutex> > move()
+ {
+ return detail::thread_move_t<try_lock_wrapper<Mutex> >(*this);
+ }
+
+ try_lock_wrapper& operator=(detail::thread_move_t<try_lock_wrapper<Mutex> > other)
+ {
+ try_lock_wrapper temp(other);
+ swap(temp);
+ return *this;
+ }
+
+ void swap(try_lock_wrapper& other)
+ {
+ base::swap(other);
+ }
+ void swap(detail::thread_move_t<try_lock_wrapper<Mutex> > other)
+ {
+ base::swap(*other);
+ }
+
+ void lock()
+ {
+ base::lock();
+ }
+ bool try_lock()
+ {
+ return base::try_lock();
+ }
+ void unlock()
+ {
+ base::unlock();
+ }
+ bool owns_lock() const
+ {
+ return base::owns_lock();
+ }
+ Mutex* mutex() const
+ {
+ return base::mutex();
+ }
+ Mutex* release()
+ {
+ return base::release();
+ }
+ bool operator!() const
+ {
+ return !this->owns_lock();
+ }
+
+ typedef typename base::bool_type bool_type;
+ operator bool_type() const
+ {
+ return static_cast<base const&>(*this);
+ }
+ };
+
+ template<typename Mutex>
+ void swap(try_lock_wrapper<Mutex>& lhs,try_lock_wrapper<Mutex>& rhs)
+ {
+ lhs.swap(rhs);
+ }
+
+ template<typename MutexType1,typename MutexType2>
+ unsigned try_lock_internal(MutexType1& m1,MutexType2& m2)
+ {
+ boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock);
+ if(!l1)
+ {
+ return 1;
+ }
+ if(!m2.try_lock())
+ {
+ return 2;
+ }
+ l1.release();
+ return 0;
+ }
+
+ template<typename MutexType1,typename MutexType2,typename MutexType3>
+ unsigned try_lock_internal(MutexType1& m1,MutexType2& m2,MutexType3& m3)
+ {
+ boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock);
+ if(!l1)
+ {
+ return 1;
+ }
+ if(unsigned const failed_lock=try_lock_internal(m2,m3))
+ {
+ return failed_lock+1;
+ }
+ l1.release();
+ return 0;
+ }
+
+
+ template<typename MutexType1,typename MutexType2,typename MutexType3,
+ typename MutexType4>
+ unsigned try_lock_internal(MutexType1& m1,MutexType2& m2,MutexType3& m3,
+ MutexType4& m4)
+ {
+ boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock);
+ if(!l1)
+ {
+ return 1;
+ }
+ if(unsigned const failed_lock=try_lock_internal(m2,m3,m4))
+ {
+ return failed_lock+1;
+ }
+ l1.release();
+ return 0;
+ }
+
+ template<typename MutexType1,typename MutexType2,typename MutexType3,
+ typename MutexType4,typename MutexType5>
+ unsigned try_lock_internal(MutexType1& m1,MutexType2& m2,MutexType3& m3,
+ MutexType4& m4,MutexType5& m5)
+ {
+ boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock);
+ if(!l1)
+ {
+ return 1;
+ }
+ if(unsigned const failed_lock=try_lock_internal(m2,m3,m4,m5))
+ {
+ return failed_lock+1;
+ }
+ l1.release();
+ return 0;
+ }
+
+
+ template<typename MutexType1,typename MutexType2>
+ unsigned lock_helper(MutexType1& m1,MutexType2& m2)
+ {
+ boost::unique_lock<MutexType1> l1(m1);
+ if(!m2.try_lock())
+ {
+ return 1;
+ }
+ l1.release();
+ return 0;
+ }
+
+ template<typename MutexType1,typename MutexType2,typename MutexType3>
+ unsigned lock_helper(MutexType1& m1,MutexType2& m2,MutexType3& m3)
+ {
+ boost::unique_lock<MutexType1> l1(m1);
+ if(unsigned const failed_lock=try_lock_internal(m2,m3))
+ {
+ return failed_lock;
+ }
+ l1.release();
+ return 0;
+ }
+
+ template<typename MutexType1,typename MutexType2,typename MutexType3,
+ typename MutexType4>
+ unsigned lock_helper(MutexType1& m1,MutexType2& m2,MutexType3& m3,
+ MutexType4& m4)
+ {
+ boost::unique_lock<MutexType1> l1(m1);
+ if(unsigned const failed_lock=try_lock_internal(m2,m3,m4))
+ {
+ return failed_lock;
+ }
+ l1.release();
+ return 0;
+ }
+
+ template<typename MutexType1,typename MutexType2,typename MutexType3,
+ typename MutexType4,typename MutexType5>
+ unsigned lock_helper(MutexType1& m1,MutexType2& m2,MutexType3& m3,
+ MutexType4& m4,MutexType5& m5)
+ {
+ boost::unique_lock<MutexType1> l1(m1);
+ if(unsigned const failed_lock=try_lock_internal(m2,m3,m4,m5))
+ {
+ return failed_lock;
+ }
+ l1.release();
+ return 0;
+ }
+ }
+
+ template<typename MutexType1,typename MutexType2>
+ typename enable_if<is_mutex_type<MutexType1>, void>::type lock(MutexType1& m1,MutexType2& m2)
+ {
+ unsigned const lock_count=2;
+ unsigned lock_first=0;
+ while(true)
+ {
+ switch(lock_first)
+ {
+ case 0:
+ lock_first=detail::lock_helper(m1,m2);
+ if(!lock_first)
+ return;
+ break;
+ case 1:
+ lock_first=detail::lock_helper(m2,m1);
+ if(!lock_first)
+ return;
+ lock_first=(lock_first+1)%lock_count;
+ break;
+ }
+ }
+ }
+
+ template<typename MutexType1,typename MutexType2,typename MutexType3>
+ void lock(MutexType1& m1,MutexType2& m2,MutexType3& m3)
+ {
+ unsigned const lock_count=3;
+ unsigned lock_first=0;
+ while(true)
+ {
+ switch(lock_first)
+ {
+ case 0:
+ lock_first=detail::lock_helper(m1,m2,m3);
+ if(!lock_first)
+ return;
+ break;
+ case 1:
+ lock_first=detail::lock_helper(m2,m3,m1);
+ if(!lock_first)
+ return;
+ lock_first=(lock_first+1)%lock_count;
+ break;
+ case 2:
+ lock_first=detail::lock_helper(m3,m1,m2);
+ if(!lock_first)
+ return;
+ lock_first=(lock_first+2)%lock_count;
+ break;
+ }
+ }
+ }
+
+ template<typename MutexType1,typename MutexType2,typename MutexType3,
+ typename MutexType4>
+ void lock(MutexType1& m1,MutexType2& m2,MutexType3& m3,
+ MutexType4& m4)
+ {
+ unsigned const lock_count=4;
+ unsigned lock_first=0;
+ while(true)
+ {
+ switch(lock_first)
+ {
+ case 0:
+ lock_first=detail::lock_helper(m1,m2,m3,m4);
+ if(!lock_first)
+ return;
+ break;
+ case 1:
+ lock_first=detail::lock_helper(m2,m3,m4,m1);
+ if(!lock_first)
+ return;
+ lock_first=(lock_first+1)%lock_count;
+ break;
+ case 2:
+ lock_first=detail::lock_helper(m3,m4,m1,m2);
+ if(!lock_first)
+ return;
+ lock_first=(lock_first+2)%lock_count;
+ break;
+ case 3:
+ lock_first=detail::lock_helper(m4,m1,m2,m3);
+ if(!lock_first)
+ return;
+ lock_first=(lock_first+3)%lock_count;
+ break;
+ }
+ }
+ }
+
+ template<typename MutexType1,typename MutexType2,typename MutexType3,
+ typename MutexType4,typename MutexType5>
+ void lock(MutexType1& m1,MutexType2& m2,MutexType3& m3,
+ MutexType4& m4,MutexType5& m5)
+ {
+ unsigned const lock_count=5;
+ unsigned lock_first=0;
+ while(true)
+ {
+ switch(lock_first)
+ {
+ case 0:
+ lock_first=detail::lock_helper(m1,m2,m3,m4,m5);
+ if(!lock_first)
+ return;
+ break;
+ case 1:
+ lock_first=detail::lock_helper(m2,m3,m4,m5,m1);
+ if(!lock_first)
+ return;
+ lock_first=(lock_first+1)%lock_count;
+ break;
+ case 2:
+ lock_first=detail::lock_helper(m3,m4,m5,m1,m2);
+ if(!lock_first)
+ return;
+ lock_first=(lock_first+2)%lock_count;
+ break;
+ case 3:
+ lock_first=detail::lock_helper(m4,m5,m1,m2,m3);
+ if(!lock_first)
+ return;
+ lock_first=(lock_first+3)%lock_count;
+ break;
+ case 4:
+ lock_first=detail::lock_helper(m5,m1,m2,m3,m4);
+ if(!lock_first)
+ return;
+ lock_first=(lock_first+4)%lock_count;
+ break;
+ }
+ }
+ }
+
+ template<typename MutexType1,typename MutexType2>
+ typename enable_if<is_mutex_type<MutexType1>, int>::type try_lock(MutexType1& m1,MutexType2& m2)
+ {
+ return ((int)detail::try_lock_internal(m1,m2))-1;
+ }
+
+ template<typename MutexType1,typename MutexType2,typename MutexType3>
+ int try_lock(MutexType1& m1,MutexType2& m2,MutexType3& m3)
+ {
+ return ((int)detail::try_lock_internal(m1,m2,m3))-1;
+ }
+
+ template<typename MutexType1,typename MutexType2,typename MutexType3,typename MutexType4>
+ int try_lock(MutexType1& m1,MutexType2& m2,MutexType3& m3,MutexType4& m4)
+ {
+ return ((int)detail::try_lock_internal(m1,m2,m3,m4))-1;
+ }
+
+ template<typename MutexType1,typename MutexType2,typename MutexType3,typename MutexType4,typename MutexType5>
+ int try_lock(MutexType1& m1,MutexType2& m2,MutexType3& m3,MutexType4& m4,MutexType5& m5)
+ {
+ return ((int)detail::try_lock_internal(m1,m2,m3,m4,m5))-1;
+ }
+
+
+ template<typename Iterator>
+ typename disable_if<is_mutex_type<Iterator>, void>::type lock(Iterator begin,Iterator end);
+
+ namespace detail
+ {
+ template<typename Iterator>
+ struct range_lock_guard
+ {
+ Iterator begin;
+ Iterator end;
+
+ range_lock_guard(Iterator begin_,Iterator end_):
+ begin(begin_),end(end_)
+ {
+ lock(begin,end);
+ }
+
+ void release()
+ {
+ begin=end;
+ }
+
+ ~range_lock_guard()
+ {
+ for(;begin!=end;++begin)
+ {
+ begin->unlock();
+ }
+ }
+ };
+ }
+
+ template<typename Iterator>
+ typename disable_if<is_mutex_type<Iterator>, Iterator>::type try_lock(Iterator begin,Iterator end)
+ {
+ if(begin==end)
+ {
+ return end;
+ }
+ typedef typename std::iterator_traits<Iterator>::value_type lock_type;
+ unique_lock<lock_type> guard(*begin,try_to_lock);
+
+ if(!guard.owns_lock())
+ {
+ return begin;
+ }
+ Iterator const failed=try_lock(++begin,end);
+ if(failed==end)
+ {
+ guard.release();
+ }
+
+ return failed;
+ }
+
+ template<typename Iterator>
+ typename disable_if<is_mutex_type<Iterator>, void>::type lock(Iterator begin,Iterator end)
+ {
+ typedef typename std::iterator_traits<Iterator>::value_type lock_type;
+
+ if(begin==end)
+ {
+ return;
+ }
+ bool start_with_begin=true;
+ Iterator second=begin;
+ ++second;
+ Iterator next=second;
+
+ for(;;)
+ {
+ unique_lock<lock_type> begin_lock(*begin,defer_lock);
+ if(start_with_begin)
+ {
+ begin_lock.lock();
+ Iterator const failed_lock=try_lock(next,end);
+ if(failed_lock==end)
+ {
+ begin_lock.release();
+ return;
+ }
+ start_with_begin=false;
+ next=failed_lock;
+ }
+ else
+ {
+ detail::range_lock_guard<Iterator> guard(next,end);
+ if(begin_lock.try_lock())
+ {
+ Iterator const failed_lock=try_lock(second,next);
+ if(failed_lock==next)
+ {
+ begin_lock.release();
+ guard.release();
+ return;
+ }
+ start_with_begin=false;
+ next=failed_lock;
+ }
+ else
+ {
+ start_with_begin=true;
+ next=second;
+ }
+ }
+ }
+ }
+
 }
 
+#include <boost/config/abi_suffix.hpp>
+
 #endif

Modified: branches/release/boost/thread/once.hpp
==============================================================================
--- branches/release/boost/thread/once.hpp (original)
+++ branches/release/boost/thread/once.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -18,6 +18,8 @@
 #error "Boost threads unavailable on this platform"
 #endif
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
     inline void call_once(void (*func)(),once_flag& flag)
@@ -26,4 +28,6 @@
     }
 }
 
+#include <boost/config/abi_suffix.hpp>
+
 #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 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -3,32 +3,17 @@
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
-// (C) Copyright 2007 Anthony Williams
+// (C) Copyright 2007-8 Anthony Williams
 
-#include <limits.h>
-#include <boost/assert.hpp>
-#include <algorithm>
-#include <pthread.h>
 #include "timespec.hpp"
 #include "pthread_mutex_scoped_lock.hpp"
 #include "thread_data.hpp"
 #include "condition_variable_fwd.hpp"
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
- inline condition_variable::condition_variable()
- {
- int const res=pthread_cond_init(&cond,NULL);
- if(res)
- {
- throw thread_resource_error();
- }
- }
- inline condition_variable::~condition_variable()
- {
- BOOST_VERIFY(!pthread_cond_destroy(&cond));
- }
-
     inline void condition_variable::wait(unique_lock<mutex>& m)
     {
         detail::interruption_checker check_for_interruption(&cond);
@@ -175,4 +160,6 @@
 
 }
 
+#include <boost/config/abi_suffix.hpp>
+
 #endif

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 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -3,14 +3,17 @@
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
-// (C) Copyright 2007 Anthony Williams
+// (C) Copyright 2007-8 Anthony Williams
 
+#include <boost/assert.hpp>
 #include <pthread.h>
 #include <boost/thread/mutex.hpp>
 #include <boost/thread/locks.hpp>
 #include <boost/thread/thread_time.hpp>
 #include <boost/thread/xtime.hpp>
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
     class condition_variable
@@ -22,8 +25,18 @@
         condition_variable& operator=(condition_variable&);
 
     public:
- condition_variable();
- ~condition_variable();
+ condition_variable()
+ {
+ int const res=pthread_cond_init(&cond,NULL);
+ if(res)
+ {
+ throw thread_resource_error();
+ }
+ }
+ ~condition_variable()
+ {
+ BOOST_VERIFY(!pthread_cond_destroy(&cond));
+ }
 
         void wait(unique_lock<mutex>& m);
 
@@ -58,9 +71,17 @@
             return timed_wait(m,get_system_time()+wait_duration,pred);
         }
 
+ typedef pthread_cond_t* native_handle_type;
+ native_handle_type native_handle()
+ {
+ return &cond;
+ }
+
         void notify_one();
         void notify_all();
     };
 }
 
+#include <boost/config/abi_suffix.hpp>
+
 #endif

Modified: branches/release/boost/thread/pthread/mutex.hpp
==============================================================================
--- branches/release/boost/thread/pthread/mutex.hpp (original)
+++ branches/release/boost/thread/pthread/mutex.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -1,6 +1,6 @@
 #ifndef BOOST_THREAD_PTHREAD_MUTEX_HPP
 #define BOOST_THREAD_PTHREAD_MUTEX_HPP
-// (C) Copyright 2007 Anthony Williams
+// (C) Copyright 2007-8 Anthony Williams
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
@@ -11,9 +11,6 @@
 #include <boost/thread/locks.hpp>
 #include <boost/thread/thread_time.hpp>
 #include <boost/assert.hpp>
-#ifndef WIN32
-#include <unistd.h>
-#endif
 #include <errno.h>
 #include "timespec.hpp"
 #include "pthread_mutex_scoped_lock.hpp"
@@ -24,6 +21,8 @@
 #endif
 #endif
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
     class mutex:
@@ -69,7 +68,7 @@
         }
 
         typedef unique_lock<mutex> scoped_lock;
- typedef scoped_lock scoped_try_lock;
+ typedef detail::try_lock_wrapper<mutex> scoped_try_lock;
     };
 
     typedef mutex try_mutex;
@@ -136,9 +135,16 @@
         {
             struct timespec const timeout=detail::get_timespec(abs_time);
             int const res=pthread_mutex_timedlock(&m,&timeout);
- BOOST_ASSERT(!res || res==EBUSY);
+ BOOST_ASSERT(!res || res==ETIMEDOUT);
             return !res;
         }
+
+ typedef pthread_mutex_t* native_handle_type;
+ native_handle_type native_handle()
+ {
+ return &m;
+ }
+
 #else
         void lock()
         {
@@ -187,11 +193,13 @@
 #endif
 
         typedef unique_lock<timed_mutex> scoped_timed_lock;
- typedef scoped_timed_lock scoped_try_lock;
+ typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;
         typedef scoped_timed_lock scoped_lock;
     };
 
 }
 
+#include <boost/config/abi_suffix.hpp>
+
 
 #endif

Modified: branches/release/boost/thread/pthread/once.hpp
==============================================================================
--- branches/release/boost/thread/pthread/once.hpp (original)
+++ branches/release/boost/thread/pthread/once.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -3,7 +3,7 @@
 
 // once.hpp
 //
-// (C) Copyright 2007 Anthony Williams
+// (C) Copyright 2007-8 Anthony Williams
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -17,7 +17,10 @@
 #include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
 #include <boost/cstdint.hpp>
 
-namespace boost {
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
 
     struct once_flag
     {
@@ -82,4 +85,6 @@
     }
 }
 
+#include <boost/config/abi_suffix.hpp>
+
 #endif

Modified: branches/release/boost/thread/pthread/pthread_mutex_scoped_lock.hpp
==============================================================================
--- branches/release/boost/thread/pthread/pthread_mutex_scoped_lock.hpp (original)
+++ branches/release/boost/thread/pthread/pthread_mutex_scoped_lock.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -1,6 +1,6 @@
 #ifndef BOOST_PTHREAD_MUTEX_SCOPED_LOCK_HPP
 #define BOOST_PTHREAD_MUTEX_SCOPED_LOCK_HPP
-// (C) Copyright 2007 Anthony Williams
+// (C) Copyright 2007-8 Anthony Williams
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -9,6 +9,8 @@
 #include <pthread.h>
 #include <boost/assert.hpp>
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
     namespace pthread
@@ -47,4 +49,6 @@
     }
 }
 
+#include <boost/config/abi_suffix.hpp>
+
 #endif

Modified: branches/release/boost/thread/pthread/recursive_mutex.hpp
==============================================================================
--- branches/release/boost/thread/pthread/recursive_mutex.hpp (original)
+++ branches/release/boost/thread/pthread/recursive_mutex.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -1,6 +1,6 @@
 #ifndef BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP
 #define BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP
-// (C) Copyright 2007 Anthony Williams
+// (C) Copyright 2007-8 Anthony Williams
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
@@ -11,7 +11,7 @@
 #include <boost/thread/locks.hpp>
 #include <boost/thread/thread_time.hpp>
 #include <boost/assert.hpp>
-#ifndef WIN32
+#ifndef _WIN32
 #include <unistd.h>
 #endif
 #include <boost/date_time/posix_time/conversion.hpp>
@@ -25,6 +25,8 @@
 #endif
 #endif
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
     class recursive_mutex:
@@ -76,8 +78,15 @@
             BOOST_ASSERT(!res || res==EBUSY);
             return !res;
         }
+
+ typedef pthread_mutex_t* native_handle_type;
+ native_handle_type native_handle()
+ {
+ return &m;
+ }
+
         typedef unique_lock<recursive_mutex> scoped_lock;
- typedef scoped_lock scoped_try_lock;
+ typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock;
     };
 
     typedef recursive_mutex recursive_try_mutex;
@@ -171,6 +180,13 @@
             BOOST_ASSERT(!res || res==EBUSY);
             return !res;
         }
+
+ typedef pthread_mutex_t* native_handle_type;
+ native_handle_type native_handle()
+ {
+ return &m;
+ }
+
 #else
         void lock()
         {
@@ -239,11 +255,12 @@
 #endif
 
         typedef unique_lock<recursive_timed_mutex> scoped_timed_lock;
- typedef scoped_timed_lock scoped_try_lock;
+ typedef detail::try_lock_wrapper<recursive_timed_mutex> scoped_try_lock;
         typedef scoped_timed_lock scoped_lock;
     };
 
 }
 
+#include <boost/config/abi_suffix.hpp>
 
 #endif

Modified: branches/release/boost/thread/pthread/shared_mutex.hpp
==============================================================================
--- branches/release/boost/thread/pthread/shared_mutex.hpp (original)
+++ branches/release/boost/thread/pthread/shared_mutex.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -1,7 +1,7 @@
 #ifndef BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
 #define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
 
-// (C) Copyright 2006-7 Anthony Williams
+// (C) Copyright 2006-8 Anthony Williams
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -13,6 +13,8 @@
 #include <boost/thread/thread.hpp>
 #include <boost/thread/condition_variable.hpp>
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
     class shared_mutex
@@ -44,7 +46,7 @@
     public:
         shared_mutex()
         {
- state_data state_={0};
+ state_data state_={0,0,0,0};
             state=state_;
         }
 
@@ -57,23 +59,11 @@
             boost::this_thread::disable_interruption do_not_disturb;
             boost::mutex::scoped_lock lock(state_change);
                 
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4127)
-#endif
- while(true)
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
+ while(state.exclusive || state.exclusive_waiting_blocked)
             {
- if(!state.exclusive && !state.exclusive_waiting_blocked)
- {
- ++state.shared_count;
- return;
- }
-
                 shared_cond.wait(lock);
             }
+ ++state.shared_count;
         }
 
         bool try_lock_shared()
@@ -96,26 +86,21 @@
             boost::this_thread::disable_interruption do_not_disturb;
             boost::mutex::scoped_lock lock(state_change);
                 
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4127)
-#endif
- while(true)
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
+ while(state.exclusive || state.exclusive_waiting_blocked)
             {
- if(!state.exclusive && !state.exclusive_waiting_blocked)
- {
- ++state.shared_count;
- return true;
- }
-
                 if(!shared_cond.timed_wait(lock,timeout))
                 {
                     return false;
                 }
             }
+ ++state.shared_count;
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock_shared(TimeDuration const & relative_time)
+ {
+ return timed_lock_shared(get_system_time()+relative_time);
         }
 
         void unlock_shared()
@@ -144,56 +129,41 @@
             boost::this_thread::disable_interruption do_not_disturb;
             boost::mutex::scoped_lock lock(state_change);
                 
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4127)
-#endif
- while(true)
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
+ while(state.shared_count || state.exclusive)
             {
- if(state.shared_count || state.exclusive)
- {
- state.exclusive_waiting_blocked=true;
- }
- else
- {
- state.exclusive=true;
- return;
- }
+ state.exclusive_waiting_blocked=true;
                 exclusive_cond.wait(lock);
             }
+ state.exclusive=true;
         }
 
         bool timed_lock(system_time const& timeout)
         {
             boost::this_thread::disable_interruption do_not_disturb;
             boost::mutex::scoped_lock lock(state_change);
-
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4127)
-#endif
- while(true)
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
+
+ while(state.shared_count || state.exclusive)
             {
- if(state.shared_count || state.exclusive)
- {
- state.exclusive_waiting_blocked=true;
- }
- else
- {
- state.exclusive=true;
- return true;
- }
+ state.exclusive_waiting_blocked=true;
                 if(!exclusive_cond.timed_wait(lock,timeout))
                 {
- return false;
+ if(state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=false;
+ exclusive_cond.notify_one();
+ return false;
+ }
+ break;
                 }
             }
+ state.exclusive=true;
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time)
+ {
+ return timed_lock(get_system_time()+relative_time);
         }
 
         bool try_lock()
@@ -224,51 +194,38 @@
         {
             boost::this_thread::disable_interruption do_not_disturb;
             boost::mutex::scoped_lock lock(state_change);
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4127)
-#endif
- while(true)
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
+ while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
             {
- if(!state.exclusive && !state.exclusive_waiting_blocked && !state.upgrade)
- {
- ++state.shared_count;
- state.upgrade=true;
- return;
- }
-
                 shared_cond.wait(lock);
             }
+ ++state.shared_count;
+ state.upgrade=true;
         }
 
         bool timed_lock_upgrade(system_time const& timeout)
         {
             boost::this_thread::disable_interruption do_not_disturb;
             boost::mutex::scoped_lock lock(state_change);
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4127)
-#endif
- while(true)
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
+ while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
             {
- if(!state.exclusive && !state.exclusive_waiting_blocked && !state.upgrade)
- {
- ++state.shared_count;
- state.upgrade=true;
- return true;
- }
-
                 if(!shared_cond.timed_wait(lock,timeout))
                 {
- return false;
+ if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ return false;
+ }
+ break;
                 }
             }
+ ++state.shared_count;
+ state.upgrade=true;
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock_upgrade(TimeDuration const & relative_time)
+ {
+ return timed_lock(get_system_time()+relative_time);
         }
 
         bool try_lock_upgrade()
@@ -304,23 +261,12 @@
             boost::this_thread::disable_interruption do_not_disturb;
             boost::mutex::scoped_lock lock(state_change);
             --state.shared_count;
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4127)
-#endif
- while(true)
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
+ while(state.shared_count)
             {
- if(!state.shared_count)
- {
- state.upgrade=false;
- state.exclusive=true;
- break;
- }
                 upgrade_cond.wait(lock);
             }
+ state.upgrade=false;
+ state.exclusive=true;
         }
 
         void unlock_and_lock_upgrade()
@@ -352,5 +298,6 @@
     };
 }
 
+#include <boost/config/abi_suffix.hpp>
 
 #endif

Deleted: branches/release/boost/thread/pthread/thread.hpp
==============================================================================
--- branches/release/boost/thread/pthread/thread.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
+++ (empty file)
@@ -1,329 +0,0 @@
-#ifndef BOOST_THREAD_THREAD_PTHREAD_HPP
-#define BOOST_THREAD_THREAD_PTHREAD_HPP
-// 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>
-
-#include <boost/utility.hpp>
-#include <boost/function.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/condition_variable.hpp>
-#include <list>
-#include <memory>
-
-#include <pthread.h>
-#include <boost/optional.hpp>
-#include <boost/thread/detail/move.hpp>
-#include <boost/shared_ptr.hpp>
-#include "thread_data.hpp"
-#include <stdlib.h>
-
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4251)
-#endif
-
-namespace boost
-{
- class thread;
-
- namespace detail
- {
- class thread_id;
- }
-
- namespace this_thread
- {
- BOOST_THREAD_DECL detail::thread_id get_id();
- }
-
- namespace detail
- {
- class thread_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();
- public:
- thread_id():
- thread_data()
- {}
-
- bool operator==(const thread_id& y) const
- {
- 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 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.thread_data)
- {
- return os<<x.thread_data;
- }
- else
- {
- return os<<"{Not-any-thread}";
- }
- }
- };
- }
-
- struct xtime;
- class BOOST_THREAD_DECL thread
- {
- private:
- thread(thread&);
- thread& operator=(thread&);
-
- template<typename F>
- struct thread_data:
- detail::thread_data_base
- {
- F f;
-
- thread_data(F f_):
- f(f_)
- {}
- thread_data(detail::thread_move_t<F> f_):
- f(f_)
- {}
-
- void run()
- {
- f();
- }
- };
-
- mutable boost::mutex thread_info_mutex;
- detail::thread_data_ptr thread_info;
-
- void start_thread();
-
- explicit thread(detail::thread_data_ptr data);
-
- detail::thread_data_ptr get_thread_info() const;
-
- public:
- thread();
- ~thread();
-
- template <class F>
- explicit thread(F f):
- thread_info(new thread_data<F>(f))
- {
- start_thread();
- }
- template <class F>
- thread(detail::thread_move_t<F> f):
- thread_info(new thread_data<F>(f))
- {
- start_thread();
- }
-
- 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);
-
- typedef detail::thread_id id;
-
- id get_id() const;
-
- bool joinable() const;
- void join();
- bool timed_join(const system_time& wait_until);
-
- template<typename TimeDuration>
- inline bool timed_join(TimeDuration const& rel_time)
- {
- return timed_join(get_system_time()+rel_time);
- }
- void detach();
-
- static unsigned hardware_concurrency();
-
- // backwards compatibility
- bool operator==(const thread& other) const;
- bool operator!=(const thread& other) const;
-
- static void sleep(const system_time& xt);
- static void yield();
-
- // extensions
- void interrupt();
- 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
- {
- F& f;
-
- thread_data(boost::reference_wrapper<F> f_):
- f(f_)
- {}
-
- void run()
- {
- f();
- }
- };
-
- namespace this_thread
- {
- class BOOST_THREAD_DECL disable_interruption
- {
- disable_interruption(const disable_interruption&);
- disable_interruption& operator=(const disable_interruption&);
-
- bool interruption_was_enabled;
- friend class restore_interruption;
- public:
- disable_interruption();
- ~disable_interruption();
- };
-
- class BOOST_THREAD_DECL restore_interruption
- {
- restore_interruption(const restore_interruption&);
- restore_interruption& operator=(const restore_interruption&);
- public:
- explicit restore_interruption(disable_interruption& d);
- ~restore_interruption();
- };
-
- 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();
-
- inline void yield()
- {
- thread::yield();
- }
-
- template<typename TimeDuration>
- inline void sleep(TimeDuration const& rel_time)
- {
- thread::sleep(get_system_time()+rel_time);
- }
- }
-
- namespace detail
- {
- struct thread_exit_function_base
- {
- virtual ~thread_exit_function_base()
- {}
- virtual void operator()() const=0;
- };
-
- template<typename F>
- struct thread_exit_function:
- thread_exit_function_base
- {
- F f;
-
- thread_exit_function(F f_):
- f(f_)
- {}
-
- void operator()() const
- {
- f();
- }
- };
-
- BOOST_THREAD_DECL void add_thread_exit_function(thread_exit_function_base*);
- }
-
- namespace this_thread
- {
- template<typename F>
- inline void at_thread_exit(F f)
- {
- detail::thread_exit_function_base* const thread_exit_func=new detail::thread_exit_function<F>(f);
- detail::add_thread_exit_function(thread_exit_func);
- }
- }
-
- class BOOST_THREAD_DECL thread_group
- {
- public:
- thread_group();
- ~thread_group();
-
- thread* create_thread(const function0<void>& threadfunc);
- void add_thread(thread* thrd);
- void remove_thread(thread* thrd);
- void join_all();
- void interrupt_all();
- size_t size() const;
-
- private:
- thread_group(thread_group&);
- void operator=(thread_group&);
-
- std::list<thread*> m_threads;
- mutex m_mutex;
- };
-} // namespace boost
-
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
-
-
-#endif

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 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -6,6 +6,7 @@
 // (C) Copyright 2007 Anthony Williams
 
 #include <boost/thread/detail/config.hpp>
+#include <boost/thread/exceptions.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/enable_shared_from_this.hpp>
 #include <boost/thread/mutex.hpp>
@@ -13,11 +14,12 @@
 #include <pthread.h>
 #include "condition_variable_fwd.hpp"
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
- class thread_interrupted
- {};
-
+ class thread;
+
     namespace detail
     {
         struct thread_exit_callback_node;
@@ -26,7 +28,7 @@
         struct thread_data_base;
         typedef boost::shared_ptr<thread_data_base> thread_data_ptr;
         
- struct thread_data_base:
+ struct BOOST_THREAD_DECL thread_data_base:
             enable_shared_from_this<thread_data_base>
         {
             thread_data_ptr self;
@@ -51,8 +53,9 @@
                 interrupt_requested(false),
                 current_cond(0)
             {}
- virtual ~thread_data_base()
- {}
+ virtual ~thread_data_base();
+
+ typedef pthread_t native_handle_type;
 
             virtual void run()=0;
         };
@@ -95,7 +98,21 @@
             }
         };
     }
+
+ namespace this_thread
+ {
+ void BOOST_THREAD_DECL yield();
+
+ void BOOST_THREAD_DECL sleep(system_time const& abs_time);
+
+ template<typename TimeDuration>
+ inline void sleep(TimeDuration const& rel_time)
+ {
+ this_thread::sleep(get_system_time()+rel_time);
+ }
+ }
 }
 
+#include <boost/config/abi_suffix.hpp>
 
 #endif

Modified: branches/release/boost/thread/pthread/timespec.hpp
==============================================================================
--- branches/release/boost/thread/pthread/timespec.hpp (original)
+++ branches/release/boost/thread/pthread/timespec.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -1,6 +1,6 @@
 #ifndef BOOST_THREAD_PTHREAD_TIMESPEC_HPP
 #define BOOST_THREAD_PTHREAD_TIMESPEC_HPP
-// (C) Copyright 2007 Anthony Williams
+// (C) Copyright 2007-8 Anthony Williams
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -8,6 +8,12 @@
 
 #include <boost/thread/thread_time.hpp>
 #include <boost/date_time/posix_time/conversion.hpp>
+#include <pthread.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+#include <boost/config/abi_prefix.hpp>
 
 namespace boost
 {
@@ -15,14 +21,16 @@
     {
         inline struct timespec get_timespec(boost::system_time const& abs_time)
         {
- struct timespec timeout={0};
+ struct timespec timeout={0,0};
             boost::posix_time::time_duration const time_since_epoch=abs_time-boost::posix_time::from_time_t(0);
             
             timeout.tv_sec=time_since_epoch.total_seconds();
- timeout.tv_nsec=time_since_epoch.fractional_seconds()*(1000000000/time_since_epoch.ticks_per_second());
+ timeout.tv_nsec=(long)(time_since_epoch.fractional_seconds()*(1000000000l/time_since_epoch.ticks_per_second()));
             return timeout;
         }
     }
 }
 
+#include <boost/config/abi_suffix.hpp>
+
 #endif

Deleted: branches/release/boost/thread/pthread/tss.hpp
==============================================================================
--- branches/release/boost/thread/pthread/tss.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
+++ (empty file)
@@ -1,103 +0,0 @@
-#ifndef BOOST_THREAD_PTHREAD_TSS_HPP
-#define BOOST_THREAD_PTHREAD_TSS_HPP
-
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-// (C) Copyright 2007 Anthony Williams
-
-#include <boost/thread/detail/config.hpp>
-#include <boost/shared_ptr.hpp>
-
-namespace boost
-{
- namespace detail
- {
- struct tss_cleanup_function
- {
- virtual ~tss_cleanup_function()
- {}
-
- virtual void operator()(void* data)=0;
- };
-
- BOOST_THREAD_DECL void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing);
- BOOST_THREAD_DECL void* get_tss_data(void const* key);
- }
-
- template <typename T>
- class thread_specific_ptr
- {
- private:
- thread_specific_ptr(thread_specific_ptr&);
- thread_specific_ptr& operator=(thread_specific_ptr&);
-
- struct delete_data:
- detail::tss_cleanup_function
- {
- void operator()(void* data)
- {
- delete static_cast<T*>(data);
- }
- };
-
- struct run_custom_cleanup_function:
- detail::tss_cleanup_function
- {
- void (*cleanup_function)(T*);
-
- explicit run_custom_cleanup_function(void (*cleanup_function_)(T*)):
- cleanup_function(cleanup_function_)
- {}
-
- void operator()(void* data)
- {
- cleanup_function(static_cast<T*>(data));
- }
- };
-
-
- boost::shared_ptr<detail::tss_cleanup_function> cleanup;
-
- public:
- thread_specific_ptr():
- cleanup(new delete_data)
- {}
- explicit thread_specific_ptr(void (*func_)(T*)):
- cleanup(new run_custom_cleanup_function(func_))
- {}
- ~thread_specific_ptr()
- {
- reset();
- }
-
- T* get() const
- {
- return static_cast<T*>(detail::get_tss_data(this));
- }
- T* operator->() const
- {
- return get();
- }
- T& operator*() const
- {
- return *get();
- }
- T* release()
- {
- T* const temp=get();
- detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false);
- return temp;
- }
- void reset(T* new_value=0)
- {
- T* const current_value=get();
- if(current_value!=new_value)
- {
- detail::set_tss_data(this,cleanup,new_value,true);
- }
- }
- };
-}
-
-#endif

Modified: branches/release/boost/thread/thread.hpp
==============================================================================
--- branches/release/boost/thread/thread.hpp (original)
+++ branches/release/boost/thread/thread.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -3,7 +3,7 @@
 
 // thread.hpp
 //
-// (C) Copyright 2007 Anthony Williams
+// (C) Copyright 2007-8 Anthony Williams
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -12,11 +12,14 @@
 #include <boost/thread/detail/platform.hpp>
 
 #if defined(BOOST_THREAD_PLATFORM_WIN32)
-#include <boost/thread/win32/thread.hpp>
+#include <boost/thread/win32/thread_data.hpp>
 #elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
-#include <boost/thread/pthread/thread.hpp>
+#include <boost/thread/pthread/thread_data.hpp>
 #else
 #error "Boost threads unavailable on this platform"
 #endif
 
+#include <boost/thread/detail/thread.hpp>
+
+
 #endif

Modified: branches/release/boost/thread/thread_time.hpp
==============================================================================
--- branches/release/boost/thread/thread_time.hpp (original)
+++ branches/release/boost/thread/thread_time.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -9,6 +9,8 @@
 #include <boost/date_time/microsec_time_clock.hpp>
 #include <boost/date_time/posix_time/posix_time_types.hpp>
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
     typedef boost::posix_time::ptime system_time;
@@ -43,4 +45,6 @@
     
 }
 
+#include <boost/config/abi_suffix.hpp>
+
 #endif

Modified: branches/release/boost/thread/win32/basic_recursive_mutex.hpp
==============================================================================
--- branches/release/boost/thread/win32/basic_recursive_mutex.hpp (original)
+++ branches/release/boost/thread/win32/basic_recursive_mutex.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -3,7 +3,7 @@
 
 // basic_recursive_mutex.hpp
 //
-// (C) Copyright 2006-7 Anthony Williams
+// (C) Copyright 2006-8 Anthony Williams
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -12,6 +12,8 @@
 #include "thread_primitives.hpp"
 #include "basic_timed_mutex.hpp"
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
     namespace detail
@@ -123,4 +125,6 @@
 
 #define BOOST_BASIC_RECURSIVE_MUTEX_INITIALIZER {0}
 
+#include <boost/config/abi_suffix.hpp>
+
 #endif

Modified: branches/release/boost/thread/win32/basic_timed_mutex.hpp
==============================================================================
--- branches/release/boost/thread/win32/basic_timed_mutex.hpp (original)
+++ branches/release/boost/thread/win32/basic_timed_mutex.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -3,7 +3,7 @@
 
 // basic_timed_mutex_win32.hpp
 //
-// (C) Copyright 2006 Anthony Williams
+// (C) Copyright 2006-8 Anthony Williams
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -15,13 +15,18 @@
 #include <boost/thread/thread_time.hpp>
 #include <boost/detail/interlocked.hpp>
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
     namespace detail
     {
         struct basic_timed_mutex
         {
- BOOST_STATIC_CONSTANT(long,lock_flag_value=0x80000000);
+ BOOST_STATIC_CONSTANT(unsigned char,lock_flag_bit=31);
+ BOOST_STATIC_CONSTANT(unsigned char,event_set_flag_bit=30);
+ BOOST_STATIC_CONSTANT(long,lock_flag_value=1<<lock_flag_bit);
+ BOOST_STATIC_CONSTANT(long,event_set_flag_value=1<<event_set_flag_bit);
             long active_count;
             void* event;
 
@@ -50,18 +55,7 @@
           
             bool try_lock()
             {
- long old_count=active_count&~lock_flag_value;
- do
- {
- long const current_count=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,(old_count+1)|lock_flag_value,old_count);
- if(current_count==old_count)
- {
- return true;
- }
- old_count=current_count;
- }
- while(!(old_count&lock_flag_value));
- return false;
+ return !win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit);
             }
             
             void lock()
@@ -70,47 +64,46 @@
             }
             bool timed_lock(::boost::system_time const& wait_until)
             {
+ if(!win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit))
+ {
+ return true;
+ }
                 long old_count=active_count;
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4127)
-#endif
- while(true)
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
+ for(;;)
                 {
- long const current_count=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,(old_count+1)|lock_flag_value,old_count);
- if(current_count==old_count)
+ long const new_count=(old_count&lock_flag_value)?(old_count+1):(old_count|lock_flag_value);
+ long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count);
+ if(current==old_count)
                     {
                         break;
                     }
- old_count=current_count;
+ old_count=current;
                 }
 
                 if(old_count&lock_flag_value)
                 {
                     bool lock_acquired=false;
                     void* const sem=get_event();
- ++old_count; // we're waiting, too
+
                     do
                     {
- old_count-=(lock_flag_value+1); // there will be one less active thread on this mutex when it gets unlocked
                         if(win32::WaitForSingleObject(sem,::boost::detail::get_milliseconds_until(wait_until))!=0)
                         {
                             BOOST_INTERLOCKED_DECREMENT(&active_count);
                             return false;
                         }
- do
+ old_count&=~lock_flag_value;
+ old_count|=event_set_flag_value;
+ for(;;)
                         {
- long const current_count=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,old_count|lock_flag_value,old_count);
- if(current_count==old_count)
+ long const new_count=((old_count&lock_flag_value)?old_count:((old_count-1)|lock_flag_value))&~event_set_flag_value;
+ long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count);
+ if(current==old_count)
                             {
                                 break;
                             }
- old_count=current_count;
+ old_count=current;
                         }
- while(!(old_count&lock_flag_value));
                         lock_acquired=!(old_count&lock_flag_value);
                     }
                     while(!lock_acquired);
@@ -131,12 +124,14 @@
 
             void unlock()
             {
- long const offset=lock_flag_value+1;
- long old_count=BOOST_INTERLOCKED_EXCHANGE_ADD(&active_count,(~offset)+1);
-
- if(old_count>offset)
+ long const offset=lock_flag_value;
+ long const old_count=BOOST_INTERLOCKED_EXCHANGE_ADD(&active_count,lock_flag_value);
+ if(!(old_count&event_set_flag_value) && (old_count>offset))
                 {
- win32::SetEvent(get_event());
+ if(!win32::interlocked_bit_test_and_set(&active_count,event_set_flag_bit))
+ {
+ win32::SetEvent(get_event());
+ }
                 }
             }
 
@@ -182,4 +177,6 @@
 
 #define BOOST_BASIC_TIMED_MUTEX_INITIALIZER {0}
 
+#include <boost/config/abi_suffix.hpp>
+
 #endif

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 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -3,7 +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)
-// (C) Copyright 2007 Anthony Williams
+// (C) Copyright 2007-8 Anthony Williams
 
 #include <boost/thread/mutex.hpp>
 #include "thread_primitives.hpp"
@@ -14,85 +14,118 @@
 #include <boost/thread/thread_time.hpp>
 #include "interlocked_read.hpp"
 #include <boost/thread/xtime.hpp>
+#include <vector>
+#include <boost/intrusive_ptr.hpp>
+
+#include <boost/config/abi_prefix.hpp>
 
 namespace boost
 {
     namespace detail
     {
- class basic_condition_variable
+ class basic_cv_list_entry;
+ void intrusive_ptr_add_ref(basic_cv_list_entry * p);
+ void intrusive_ptr_release(basic_cv_list_entry * p);
+
+ class basic_cv_list_entry
         {
- boost::mutex internal_mutex;
- long total_count;
- unsigned active_generation_count;
+ private:
+ detail::win32::handle_manager semaphore;
+ detail::win32::handle_manager wake_sem;
+ long waiters;
+ bool notified;
+ long references;
 
- struct list_entry
- {
- detail::win32::handle semaphore;
- long count;
- bool notified;
+ basic_cv_list_entry(basic_cv_list_entry&);
+ void operator=(basic_cv_list_entry&);
+
+ public:
+ explicit basic_cv_list_entry(detail::win32::handle_manager const& wake_sem_):
+ semaphore(detail::win32::create_anonymous_semaphore(0,LONG_MAX)),
+ wake_sem(wake_sem_.duplicate()),
+ waiters(1),notified(false),references(0)
+ {}
 
- list_entry():
- semaphore(0),count(0),notified(0)
- {}
- };
+ static bool no_waiters(boost::intrusive_ptr<basic_cv_list_entry> const& entry)
+ {
+ return !detail::interlocked_read_acquire(&entry->waiters);
+ }
 
- BOOST_STATIC_CONSTANT(unsigned,generation_count=3);
+ void add_waiter()
+ {
+ BOOST_INTERLOCKED_INCREMENT(&waiters);
+ }
+
+ void remove_waiter()
+ {
+ BOOST_INTERLOCKED_DECREMENT(&waiters);
+ }
 
- list_entry generations[generation_count];
- detail::win32::handle wake_sem;
+ void release(unsigned count_to_release)
+ {
+ notified=true;
+ detail::win32::ReleaseSemaphore(semaphore,count_to_release,0);
+ }
 
- static bool no_waiters(list_entry const& entry)
+ void release_waiters()
             {
- return entry.count==0;
+ release(detail::interlocked_read_acquire(&waiters));
             }
 
- void shift_generations_down()
+ bool is_notified() const
             {
- list_entry* const last_active_entry=std::remove_if(generations,generations+generation_count,no_waiters);
- if(last_active_entry==generations+generation_count)
- {
- broadcast_entry(generations[generation_count-1],false);
- }
- else
- {
- active_generation_count=unsigned(last_active_entry-generations)+1;
- }
+ return notified;
+ }
 
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4996)
-#endif
- std::copy_backward(generations,generations+active_generation_count-1,generations+active_generation_count);
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
- generations[0]=list_entry();
+ bool wait(timeout wait_until)
+ {
+ return this_thread::interruptible_wait(semaphore,wait_until);
             }
 
- void broadcast_entry(list_entry& entry,bool wake)
+ bool woken()
             {
- long const count_to_wake=entry.count;
- detail::interlocked_write_release(&total_count,total_count-count_to_wake);
- if(wake)
- {
- detail::win32::ReleaseSemaphore(wake_sem,count_to_wake,0);
- }
- detail::win32::ReleaseSemaphore(entry.semaphore,count_to_wake,0);
- entry.count=0;
- dispose_entry(entry);
+ unsigned long const woken_result=detail::win32::WaitForSingleObject(wake_sem,0);
+ BOOST_ASSERT((woken_result==detail::win32::timeout) || (woken_result==0));
+ return woken_result==0;
             }
-
 
- void dispose_entry(list_entry& entry)
+ friend void intrusive_ptr_add_ref(basic_cv_list_entry * p);
+ friend void intrusive_ptr_release(basic_cv_list_entry * p);
+ };
+
+ inline void intrusive_ptr_add_ref(basic_cv_list_entry * p)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&p->references);
+ }
+
+ inline void intrusive_ptr_release(basic_cv_list_entry * p)
+ {
+ if(!BOOST_INTERLOCKED_DECREMENT(&p->references))
             {
- if(entry.semaphore)
- {
- BOOST_VERIFY(detail::win32::CloseHandle(entry.semaphore));
- entry.semaphore=0;
- }
- entry.notified=false;
+ delete p;
             }
+ }
+
+ class basic_condition_variable
+ {
+ boost::mutex internal_mutex;
+ long total_count;
+ unsigned active_generation_count;
+
+ typedef basic_cv_list_entry list_entry;
 
+ typedef boost::intrusive_ptr<list_entry> entry_ptr;
+ typedef std::vector<entry_ptr> generation_list;
+
+ generation_list generations;
+ detail::win32::handle_manager wake_sem;
+
+ void wake_waiters(long count_to_wake)
+ {
+ detail::interlocked_write_release(&total_count,total_count-count_to_wake);
+ detail::win32::ReleaseSemaphore(wake_sem,count_to_wake,0);
+ }
+
             template<typename lock_type>
             struct relocker
             {
@@ -116,75 +149,78 @@
                     
                 }
             private:
+ relocker(relocker&);
                 void operator=(relocker&);
             };
             
 
- template<typename lock_type>
- void start_wait_loop_first_time(relocker<lock_type>& locker,
- detail::win32::handle_manager& local_wake_sem)
+ entry_ptr get_wait_entry()
             {
- locker.unlock();
+ boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
+
                 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)
+
+ detail::interlocked_write_release(&total_count,total_count+1);
+ if(generations.empty() || generations.back()->is_notified())
                 {
- shift_generations_down();
+ entry_ptr new_entry(new list_entry(wake_sem));
+ generations.push_back(new_entry);
+ return new_entry;
                 }
- else if(!active_generation_count)
+ else
                 {
- active_generation_count=1;
+ generations.back()->add_waiter();
+ return generations.back();
                 }
             }
             
- template<typename lock_type>
- void start_wait_loop(relocker<lock_type>& locker,
- detail::win32::handle_manager& local_wake_sem,
- detail::win32::handle_manager& sem)
+ struct entry_manager
             {
- boost::mutex::scoped_lock internal_lock(internal_mutex);
- detail::interlocked_write_release(&total_count,total_count+1);
- if(!local_wake_sem)
+ entry_ptr const entry;
+
+ entry_manager(entry_ptr const& entry_):
+ entry(entry_)
+ {}
+
+ ~entry_manager()
                 {
- start_wait_loop_first_time(locker,local_wake_sem);
+ entry->remove_waiter();
                 }
- if(!generations[0].semaphore)
+
+ list_entry* operator->()
                 {
- generations[0].semaphore=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
- BOOST_ASSERT(generations[0].semaphore);
+ return entry.get();
                 }
- ++generations[0].count;
- sem=detail::win32::duplicate_handle(generations[0].semaphore);
- }
+
+ private:
+ void operator=(entry_manager&);
+ entry_manager(entry_manager&);
+ };
+
 
         protected:
             template<typename lock_type>
             bool do_wait(lock_type& lock,timeout wait_until)
             {
- detail::win32::handle_manager local_wake_sem;
- detail::win32::handle_manager sem;
- bool woken=false;
-
                 relocker<lock_type> locker(lock);
-
+
+ entry_manager entry(get_wait_entry());
+
+ locker.unlock();
+
+ bool woken=false;
                 while(!woken)
                 {
- start_wait_loop(locker,local_wake_sem,sem);
-
- if(!this_thread::interruptible_wait(sem,wait_until))
+ if(!entry->wait(wait_until))
                     {
                         return false;
                     }
                 
- unsigned long const woken_result=detail::win32::WaitForSingleObject(local_wake_sem,0);
- BOOST_ASSERT(woken_result==detail::win32::timeout || woken_result==0);
-
- woken=(woken_result==0);
+ woken=entry->woken();
                 }
                 return woken;
             }
@@ -202,45 +238,33 @@
         
             basic_condition_variable(const basic_condition_variable& other);
             basic_condition_variable& operator=(const basic_condition_variable& other);
+
         public:
             basic_condition_variable():
                 total_count(0),active_generation_count(0),wake_sem(0)
             {}
             
             ~basic_condition_variable()
- {
- for(unsigned i=0;i<generation_count;++i)
- {
- dispose_entry(generations[i]);
- }
- detail::win32::CloseHandle(wake_sem);
- }
+ {}
 
-
             void notify_one()
             {
                 if(detail::interlocked_read_acquire(&total_count))
                 {
- boost::mutex::scoped_lock internal_lock(internal_mutex);
- detail::win32::ReleaseSemaphore(wake_sem,1,0);
- for(unsigned generation=active_generation_count;generation!=0;--generation)
+ boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
+ if(!total_count)
+ {
+ return;
+ }
+ wake_waiters(1);
+
+ for(generation_list::iterator it=generations.begin(),
+ end=generations.end();
+ it!=end;++it)
                     {
- list_entry& entry=generations[generation-1];
- if(entry.count)
- {
- detail::interlocked_write_release(&total_count,total_count-1);
- entry.notified=true;
- detail::win32::ReleaseSemaphore(entry.semaphore,1,0);
- if(!--entry.count)
- {
- dispose_entry(entry);
- if(generation==active_generation_count)
- {
- --active_generation_count;
- }
- }
- }
+ (*it)->release(1);
                     }
+ generations.erase(std::remove_if(generations.begin(),generations.end(),&basic_cv_list_entry::no_waiters),generations.end());
                 }
             }
         
@@ -248,16 +272,20 @@
             {
                 if(detail::interlocked_read_acquire(&total_count))
                 {
- boost::mutex::scoped_lock internal_lock(internal_mutex);
- for(unsigned generation=active_generation_count;generation!=0;--generation)
+ boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
+ if(!total_count)
+ {
+ return;
+ }
+ wake_waiters(total_count);
+ for(generation_list::iterator it=generations.begin(),
+ end=generations.end();
+ it!=end;++it)
                     {
- list_entry& entry=generations[generation-1];
- if(entry.count)
- {
- broadcast_entry(entry,true);
- }
+ (*it)->release_waiters();
                     }
- active_generation_count=0;
+ generations.clear();
+ wake_sem=detail::win32::handle(0);
                 }
             }
         
@@ -265,9 +293,18 @@
     }
 
     class condition_variable:
- public detail::basic_condition_variable
+ private detail::basic_condition_variable
     {
+ private:
+ condition_variable(condition_variable&);
+ void operator=(condition_variable&);
     public:
+ condition_variable()
+ {}
+
+ using detail::basic_condition_variable::notify_one;
+ using detail::basic_condition_variable::notify_all;
+
         void wait(unique_lock<mutex>& m)
         {
             do_wait(m,detail::timeout::sentinel());
@@ -313,9 +350,18 @@
     };
     
     class condition_variable_any:
- public detail::basic_condition_variable
+ private detail::basic_condition_variable
     {
+ private:
+ condition_variable_any(condition_variable_any&);
+ void operator=(condition_variable_any&);
     public:
+ condition_variable_any()
+ {}
+
+ using detail::basic_condition_variable::notify_one;
+ using detail::basic_condition_variable::notify_all;
+
         template<typename lock_type>
         void wait(lock_type& m)
         {
@@ -367,4 +413,6 @@
 
 }
 
+#include <boost/config/abi_suffix.hpp>
+
 #endif

Modified: branches/release/boost/thread/win32/interlocked_read.hpp
==============================================================================
--- branches/release/boost/thread/win32/interlocked_read.hpp (original)
+++ branches/release/boost/thread/win32/interlocked_read.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -3,12 +3,16 @@
 
 // interlocked_read_win32.hpp
 //
-// (C) Copyright 2005-7 Anthony Williams
+// (C) Copyright 2005-8 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/detail/interlocked.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
 #ifdef BOOST_MSVC
 
 extern "C" void _ReadWriteBarrier(void);
@@ -46,8 +50,6 @@
 
 #else
 
-#include <boost/detail/interlocked.hpp>
-
 namespace boost
 {
     namespace detail
@@ -73,5 +75,6 @@
 
 #endif
 
+#include <boost/config/abi_suffix.hpp>
 
 #endif

Modified: branches/release/boost/thread/win32/mutex.hpp
==============================================================================
--- branches/release/boost/thread/win32/mutex.hpp (original)
+++ branches/release/boost/thread/win32/mutex.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -10,6 +10,8 @@
 #include <boost/thread/exceptions.hpp>
 #include <boost/thread/locks.hpp>
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
     namespace detail
@@ -32,7 +34,7 @@
         }
 
         typedef unique_lock<mutex> scoped_lock;
- typedef scoped_lock scoped_try_lock;
+ typedef detail::try_lock_wrapper<mutex> scoped_try_lock;
     };
 
     typedef mutex try_mutex;
@@ -53,9 +55,11 @@
         }
 
         typedef unique_lock<timed_mutex> scoped_timed_lock;
- typedef scoped_timed_lock scoped_try_lock;
+ typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;
         typedef scoped_timed_lock scoped_lock;
     };
 }
 
+#include <boost/config/abi_suffix.hpp>
+
 #endif

Modified: branches/release/boost/thread/win32/once.hpp
==============================================================================
--- branches/release/boost/thread/win32/once.hpp (original)
+++ branches/release/boost/thread/win32/once.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -18,6 +18,8 @@
 #include <boost/thread/win32/thread_primitives.hpp>
 #include <boost/thread/win32/interlocked_read.hpp>
 
+#include <boost/config/abi_prefix.hpp>
+
 #ifdef BOOST_NO_STDC_NAMESPACE
 namespace std
 {
@@ -129,4 +131,6 @@
     }
 }
 
+#include <boost/config/abi_suffix.hpp>
+
 #endif

Modified: branches/release/boost/thread/win32/recursive_mutex.hpp
==============================================================================
--- branches/release/boost/thread/win32/recursive_mutex.hpp (original)
+++ branches/release/boost/thread/win32/recursive_mutex.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -15,6 +15,8 @@
 #include <boost/thread/exceptions.hpp>
 #include <boost/thread/locks.hpp>
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
     class recursive_mutex:
@@ -32,7 +34,7 @@
         }
 
         typedef unique_lock<recursive_mutex> scoped_lock;
- typedef scoped_lock scoped_try_lock;
+ typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock;
     };
 
     typedef recursive_mutex recursive_try_mutex;
@@ -52,10 +54,11 @@
         }
 
         typedef unique_lock<recursive_timed_mutex> scoped_timed_lock;
- typedef scoped_timed_lock scoped_try_lock;
+ typedef detail::try_lock_wrapper<recursive_timed_mutex> scoped_try_lock;
         typedef scoped_timed_lock scoped_lock;
     };
 }
 
+#include <boost/config/abi_suffix.hpp>
 
 #endif

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 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -15,6 +15,8 @@
 #include <boost/utility.hpp>
 #include <boost/thread/thread_time.hpp>
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
     class shared_mutex:
@@ -23,12 +25,12 @@
     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;
+ unsigned shared_count:11,
+ shared_waiting:11,
+ exclusive:1,
+ upgrade:1,
+ exclusive_waiting:7,
+ exclusive_waiting_blocked:1;
 
             friend bool operator==(state_data const& lhs,state_data const& rhs)
             {
@@ -120,6 +122,12 @@
             BOOST_VERIFY(timed_lock_shared(::boost::detail::get_system_time_sentinel()));
         }
 
+ template<typename TimeDuration>
+ bool timed_lock_shared(TimeDuration const & relative_time)
+ {
+ return timed_lock_shared(get_system_time()+relative_time);
+ }
+
         bool timed_lock_shared(boost::system_time const& wait_until)
         {
 #ifdef BOOST_MSVC
@@ -269,6 +277,12 @@
             BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));
         }
 
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time)
+ {
+ return timed_lock(get_system_time()+relative_time);
+ }
+
         bool timed_lock(boost::system_time const& wait_until)
         {
 #ifdef BOOST_MSVC
@@ -325,7 +339,10 @@
                         {
                             if(new_state.exclusive_waiting)
                             {
- --new_state.exclusive_waiting;
+ if(!--new_state.exclusive_waiting)
+ {
+ new_state.exclusive_waiting_blocked=false;
+ }
                             }
                         }
                         else
@@ -617,5 +634,6 @@
     };
 }
 
+#include <boost/config/abi_suffix.hpp>
 
 #endif

Deleted: branches/release/boost/thread/win32/thread.hpp
==============================================================================
--- branches/release/boost/thread/win32/thread.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
+++ (empty file)
@@ -1,524 +0,0 @@
-#ifndef BOOST_THREAD_THREAD_WIN32_HPP
-#define BOOST_THREAD_THREAD_WIN32_HPP
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-// (C) Copyright 2007 Anthony Williams
-
-#include <exception>
-#include <boost/thread/exceptions.hpp>
-#include <ostream>
-#include <boost/thread/detail/move.hpp>
-#include <boost/intrusive_ptr.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/thread_time.hpp>
-#include "thread_primitives.hpp"
-#include "thread_heap_alloc.hpp"
-#include <boost/utility.hpp>
-#include <boost/assert.hpp>
-#include <list>
-#include <algorithm>
-#include <boost/ref.hpp>
-#include <boost/cstdint.hpp>
-#include <stdlib.h>
-#include <memory>
-
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4251)
-#endif
-
-namespace boost
-{
- class thread_interrupted
- {};
-
- namespace detail
- {
- struct thread_exit_callback_node;
- struct tss_data_node;
-
- struct thread_data_base
- {
- long count;
- detail::win32::handle_manager thread_handle;
- detail::win32::handle_manager interruption_handle;
- boost::detail::thread_exit_callback_node* thread_exit_callbacks;
- boost::detail::tss_data_node* tss_data;
- bool interruption_enabled;
- unsigned id;
-
- thread_data_base():
- count(0),thread_handle(detail::win32::invalid_handle_value),
- interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset)),
- thread_exit_callbacks(0),tss_data(0),
- interruption_enabled(true),
- id(0)
- {}
- virtual ~thread_data_base()
- {}
-
- friend void intrusive_ptr_add_ref(thread_data_base * p)
- {
- BOOST_INTERLOCKED_INCREMENT(&p->count);
- }
-
- friend void intrusive_ptr_release(thread_data_base * p)
- {
- if(!BOOST_INTERLOCKED_DECREMENT(&p->count))
- {
- detail::heap_delete(p);
- }
- }
-
- void interrupt()
- {
- BOOST_VERIFY(detail::win32::SetEvent(interruption_handle)!=0);
- }
-
-
- virtual void run()=0;
- };
-
- 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
- {
- private:
- thread(thread&);
- thread& operator=(thread&);
-
- void release_handle();
-
- template<typename F>
- struct thread_data:
- detail::thread_data_base
- {
- F f;
-
- thread_data(F f_):
- f(f_)
- {}
- thread_data(detail::thread_move_t<F> f_):
- f(f_)
- {}
-
- void run()
- {
- f();
- }
- };
-
- mutable boost::mutex thread_info_mutex;
- detail::thread_data_ptr thread_info;
-
- static unsigned __stdcall thread_start_function(void* param);
-
- void start_thread();
-
- explicit thread(detail::thread_data_ptr data);
-
- detail::thread_data_ptr get_thread_info() const;
- public:
- thread();
- ~thread();
-
- template <class F>
- explicit thread(F f):
- thread_info(detail::heap_new<thread_data<F> >(f))
- {
- start_thread();
- }
- template <class F>
- thread(detail::thread_move_t<F> f):
- thread_info(detail::heap_new<thread_data<F> >(f))
- {
- start_thread();
- }
-
- 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);
-
- class id;
- id get_id() const;
-
-
- bool joinable() const;
- void join();
- bool timed_join(const system_time& wait_until);
-
- template<typename TimeDuration>
- inline bool timed_join(TimeDuration const& rel_time)
- {
- return timed_join(get_system_time()+rel_time);
- }
- void detach();
-
- static unsigned hardware_concurrency();
-
- typedef detail::win32::handle native_handle_type;
- native_handle_type native_handle();
-
- // backwards compatibility
- bool operator==(const thread& other) const;
- bool operator!=(const thread& other) const;
-
- static void yield();
- static void sleep(const system_time& xt);
-
- // extensions
- void interrupt();
- 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
- {
- F& f;
-
- thread_data(boost::reference_wrapper<F> f_):
- f(f_)
- {}
-
- void run()
- {
- f();
- }
- };
-
-
- namespace this_thread
- {
- class BOOST_THREAD_DECL disable_interruption
- {
- disable_interruption(const disable_interruption&);
- disable_interruption& operator=(const disable_interruption&);
-
- bool interruption_was_enabled;
- friend class restore_interruption;
- public:
- disable_interruption();
- ~disable_interruption();
- };
-
- class BOOST_THREAD_DECL restore_interruption
- {
- restore_interruption(const restore_interruption&);
- restore_interruption& operator=(const restore_interruption&);
- public:
- explicit restore_interruption(disable_interruption& d);
- ~restore_interruption();
- };
-
- thread::id BOOST_THREAD_DECL get_id();
-
- 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);
- }
-
- void BOOST_THREAD_DECL interruption_point();
- bool BOOST_THREAD_DECL interruption_enabled();
- bool BOOST_THREAD_DECL interruption_requested();
-
- void BOOST_THREAD_DECL yield();
- template<typename TimeDuration>
- void sleep(TimeDuration const& rel_time)
- {
- interruptible_wait(static_cast<unsigned long>(rel_time.total_milliseconds()));
- }
- }
-
- class thread::id
- {
- private:
- detail::thread_data_ptr thread_data;
-
- id(detail::thread_data_ptr thread_data_):
- thread_data(thread_data_)
- {}
- friend class thread;
- friend id this_thread::get_id();
- public:
- id():
- thread_data(0)
- {}
-
- bool operator==(const id& y) const
- {
- return thread_data==y.thread_data;
- }
-
- bool operator!=(const id& y) const
- {
- return thread_data!=y.thread_data;
- }
-
- bool operator<(const id& y) const
- {
- return thread_data<y.thread_data;
- }
-
- bool operator>(const id& y) const
- {
- return y.thread_data<thread_data;
- }
-
- bool operator<=(const id& y) const
- {
- return !(y.thread_data<thread_data);
- }
-
- bool operator>=(const 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 id& x)
- {
- if(x.thread_data)
- {
- return os<<x.thread_data;
- }
- else
- {
- return os<<"{Not-any-thread}";
- }
- }
-
- void interrupt()
- {
- if(thread_data)
- {
- thread_data->interrupt();
- }
- }
-
- };
-
- inline bool thread::operator==(const thread& other) const
- {
- return get_id()==other.get_id();
- }
-
- inline bool thread::operator!=(const thread& other) const
- {
- return get_id()!=other.get_id();
- }
-
- namespace detail
- {
- struct thread_exit_function_base
- {
- virtual ~thread_exit_function_base()
- {}
- virtual void operator()() const=0;
- };
-
- template<typename F>
- struct thread_exit_function:
- thread_exit_function_base
- {
- F f;
-
- thread_exit_function(F f_):
- f(f_)
- {}
-
- void operator()() const
- {
- f();
- }
- };
-
- void add_thread_exit_function(thread_exit_function_base*);
- }
-
- namespace this_thread
- {
- template<typename F>
- void at_thread_exit(F f)
- {
- detail::thread_exit_function_base* const thread_exit_func=detail::heap_new<detail::thread_exit_function<F> >(f);
- detail::add_thread_exit_function(thread_exit_func);
- }
- }
-
- class thread_group:
- private noncopyable
- {
- public:
- ~thread_group()
- {
- for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
- it!=end;
- ++it)
- {
- delete *it;
- }
- }
-
- template<typename F>
- thread* create_thread(F threadfunc)
- {
- boost::lock_guard<mutex> guard(m);
- std::auto_ptr<thread> new_thread(new thread(threadfunc));
- threads.push_back(new_thread.get());
- return new_thread.release();
- }
-
- void add_thread(thread* thrd)
- {
- if(thrd)
- {
- boost::lock_guard<mutex> guard(m);
- threads.push_back(thrd);
- }
- }
-
- void remove_thread(thread* thrd)
- {
- boost::lock_guard<mutex> guard(m);
- std::list<thread*>::iterator const it=std::find(threads.begin(),threads.end(),thrd);
- if(it!=threads.end())
- {
- threads.erase(it);
- }
- }
-
- void join_all()
- {
- boost::lock_guard<mutex> guard(m);
-
- for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
- it!=end;
- ++it)
- {
- (*it)->join();
- }
- }
-
- void interrupt_all()
- {
- boost::lock_guard<mutex> guard(m);
-
- for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
- it!=end;
- ++it)
- {
- (*it)->interrupt();
- }
- }
-
- size_t size() const
- {
- boost::lock_guard<mutex> guard(m);
- return threads.size();
- }
-
- private:
- std::list<thread*> threads;
- mutable mutex m;
- };
-}
-
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
-
-#endif

Modified: branches/release/boost/thread/win32/thread_heap_alloc.hpp
==============================================================================
--- branches/release/boost/thread/win32/thread_heap_alloc.hpp (original)
+++ branches/release/boost/thread/win32/thread_heap_alloc.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -49,6 +49,8 @@
 
 #endif
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
     namespace detail
@@ -69,7 +71,7 @@
         }
             
         template<typename T>
- T* heap_new()
+ inline T* heap_new()
         {
             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
             try
@@ -84,8 +86,72 @@
             }
         }
 
+#ifdef BOOST_HAS_RVALUE_REFS
+ template<typename T,typename A1>
+ inline T* heap_new(A1&& a1)
+ {
+ void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+ try
+ {
+ T* const data=new (heap_memory) T(static_cast<A1&&>(a1));
+ return data;
+ }
+ catch(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ throw;
+ }
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1&& a1,A2&& a2)
+ {
+ void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+ try
+ {
+ T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2));
+ return data;
+ }
+ catch(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ throw;
+ }
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1&& a1,A2&& a2,A3&& a3)
+ {
+ void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+ try
+ {
+ T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
+ static_cast<A3&&>(a3));
+ return data;
+ }
+ catch(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ throw;
+ }
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1&& a1,A2&& a2,A3&& a3,A4&& a4)
+ {
+ void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+ try
+ {
+ T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
+ static_cast<A3&&>(a3),static_cast<A4&&>(a4));
+ return data;
+ }
+ catch(...)
+ {
+ free_raw_heap_memory(heap_memory);
+ throw;
+ }
+ }
+#else
         template<typename T,typename A1>
- T* heap_new(A1 a1)
+ inline T* heap_new_impl(A1 a1)
         {
             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
             try
@@ -99,9 +165,9 @@
                 throw;
             }
         }
-
+
         template<typename T,typename A1,typename A2>
- T* heap_new(A1 a1,A2 a2)
+ inline T* heap_new_impl(A1 a1,A2 a2)
         {
             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
             try
@@ -117,7 +183,7 @@
         }
 
         template<typename T,typename A1,typename A2,typename A3>
- T* heap_new(A1 a1,A2 a2,A3 a3)
+ inline T* heap_new_impl(A1 a1,A2 a2,A3 a3)
         {
             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
             try
@@ -131,9 +197,9 @@
                 throw;
             }
         }
-
+
         template<typename T,typename A1,typename A2,typename A3,typename A4>
- T* heap_new(A1 a1,A2 a2,A3 a3,A4 a4)
+ inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4)
         {
             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
             try
@@ -147,9 +213,168 @@
                 throw;
             }
         }
+
+
+ template<typename T,typename A1>
+ inline T* heap_new(A1 const& a1)
+ {
+ return heap_new_impl<T,A1 const&>(a1);
+ }
+ template<typename T,typename A1>
+ inline T* heap_new(A1& a1)
+ {
+ return heap_new_impl<T,A1&>(a1);
+ }
+
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1 const& a1,A2 const& a2)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&>(a1,a2);
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1& a1,A2 const& a2)
+ {
+ return heap_new_impl<T,A1&,A2 const&>(a1,a2);
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1 const& a1,A2& a2)
+ {
+ return heap_new_impl<T,A1 const&,A2&>(a1,a2);
+ }
+ template<typename T,typename A1,typename A2>
+ inline T* heap_new(A1& a1,A2& a2)
+ {
+ return heap_new_impl<T,A1&,A2&>(a1,a2);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3 const&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3 const&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3 const&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2& a2,A3 const& a3)
+ {
+ return heap_new_impl<T,A1&,A2&,A3 const&>(a1,a2,a3);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2 const& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1 const& a1,A2& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3&>(a1,a2,a3);
+ }
+ template<typename T,typename A1,typename A2,typename A3>
+ inline T* heap_new(A1& a1,A2& a2,A3& a3)
+ {
+ return heap_new_impl<T,A1&,A2&,A3&>(a1,a2,a3);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3& a3,A4 const& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3&,A4 const&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3 const&,A4&>(a1,a2,a3,a4);
+ }
+
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2 const&,A3&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2 const&,A3&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1 const&,A2&,A3&,A4&>(a1,a2,a3,a4);
+ }
+ template<typename T,typename A1,typename A2,typename A3,typename A4>
+ inline T* heap_new(A1& a1,A2& a2,A3& a3,A4& a4)
+ {
+ return heap_new_impl<T,A1&,A2&,A3&,A4&>(a1,a2,a3,a4);
+ }
         
+#endif
         template<typename T>
- void heap_delete(T* data)
+ inline void heap_delete(T* data)
         {
             data->~T();
             free_raw_heap_memory(data);
@@ -166,5 +391,7 @@
     }
 }
 
+#include <boost/config/abi_suffix.hpp>
+
 
 #endif

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 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -13,10 +13,12 @@
 #include <boost/config.hpp>
 #include <boost/assert.hpp>
 #include <boost/thread/exceptions.hpp>
+#include <boost/detail/interlocked.hpp>
 #include <algorithm>
 
 #if defined( BOOST_USE_WINDOWS_H )
 # include <windows.h>
+
 namespace boost
 {
     namespace detail
@@ -146,6 +148,8 @@
 # error "Win32 functions not available"
 #endif
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost
 {
     namespace detail
@@ -277,5 +281,117 @@
     }
 }
 
+#if defined(BOOST_MSVC) && (_MSC_VER>=1400) && !defined(UNDER_CE)
+#if _MSC_VER==1400
+extern "C" unsigned char _interlockedbittestandset(long *a,long b);
+extern "C" unsigned char _interlockedbittestandreset(long *a,long b);
+#else
+extern "C" unsigned char _interlockedbittestandset(volatile long *a,long b);
+extern "C" unsigned char _interlockedbittestandreset(volatile long *a,long b);
+#endif
+
+#pragma intrinsic(_interlockedbittestandset)
+#pragma intrinsic(_interlockedbittestandreset)
+
+namespace boost
+{
+ namespace detail
+ {
+ namespace win32
+ {
+ inline bool interlocked_bit_test_and_set(long* x,long bit)
+ {
+ return _interlockedbittestandset(x,bit)!=0;
+ }
+
+ inline bool interlocked_bit_test_and_reset(long* x,long bit)
+ {
+ return _interlockedbittestandreset(x,bit)!=0;
+ }
+
+ }
+ }
+}
+#define BOOST_THREAD_BTS_DEFINED
+#elif (defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)) && defined(_M_IX86)
+namespace boost
+{
+ namespace detail
+ {
+ namespace win32
+ {
+ inline bool interlocked_bit_test_and_set(long* x,long bit)
+ {
+ __asm {
+ mov eax,bit;
+ mov edx,x;
+ lock bts [edx],eax;
+ setc al;
+ };
+ }
+
+ inline bool interlocked_bit_test_and_reset(long* x,long bit)
+ {
+ __asm {
+ mov eax,bit;
+ mov edx,x;
+ lock btr [edx],eax;
+ setc al;
+ };
+ }
+
+ }
+ }
+}
+#define BOOST_THREAD_BTS_DEFINED
+#endif
+
+#ifndef BOOST_THREAD_BTS_DEFINED
+
+namespace boost
+{
+ namespace detail
+ {
+ namespace win32
+ {
+ inline bool interlocked_bit_test_and_set(long* x,long bit)
+ {
+ long const value=1<<bit;
+ long old=*x;
+ do
+ {
+ long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old|value,old);
+ if(current==old)
+ {
+ break;
+ }
+ old=current;
+ }
+ while(true);
+ return (old&value)!=0;
+ }
+
+ inline bool interlocked_bit_test_and_reset(long* x,long bit)
+ {
+ long const value=1<<bit;
+ long old=*x;
+ do
+ {
+ long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old&~value,old);
+ if(current==old)
+ {
+ break;
+ }
+ old=current;
+ }
+ while(true);
+ return (old&value)!=0;
+ }
+ }
+ }
+}
+#endif
+
+#include <boost/config/abi_suffix.hpp>
 
 #endif

Deleted: branches/release/boost/thread/win32/tss.hpp
==============================================================================
--- branches/release/boost/thread/win32/tss.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
+++ (empty file)
@@ -1,103 +0,0 @@
-#ifndef BOOST_THREAD_WIN32_TSS_HPP
-#define BOOST_THREAD_WIN32_TSS_HPP
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-// (C) Copyright 2007 Anthony Williams
-
-#include <boost/shared_ptr.hpp>
-#include "thread_heap_alloc.hpp"
-
-namespace boost
-{
- namespace detail
- {
- struct tss_cleanup_function
- {
- virtual ~tss_cleanup_function()
- {}
-
- virtual void operator()(void* data)=0;
- };
-
- BOOST_THREAD_DECL void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing);
- BOOST_THREAD_DECL void* get_tss_data(void const* key);
- }
-
- template <typename T>
- class thread_specific_ptr
- {
- private:
- thread_specific_ptr(thread_specific_ptr&);
- thread_specific_ptr& operator=(thread_specific_ptr&);
-
- struct delete_data:
- detail::tss_cleanup_function
- {
- void operator()(void* data)
- {
- delete static_cast<T*>(data);
- }
- };
-
- struct run_custom_cleanup_function:
- detail::tss_cleanup_function
- {
- void (*cleanup_function)(T*);
-
- explicit run_custom_cleanup_function(void (*cleanup_function_)(T*)):
- cleanup_function(cleanup_function_)
- {}
-
- void operator()(void* data)
- {
- cleanup_function(static_cast<T*>(data));
- }
- };
-
-
- boost::shared_ptr<detail::tss_cleanup_function> cleanup;
-
- public:
- thread_specific_ptr():
- cleanup(detail::heap_new<delete_data>(),detail::do_heap_delete<delete_data>())
- {}
- explicit thread_specific_ptr(void (*func_)(T*)):
- cleanup(detail::heap_new<run_custom_cleanup_function>(func_),detail::do_heap_delete<run_custom_cleanup_function>())
- {}
- ~thread_specific_ptr()
- {
- reset();
- }
-
- T* get() const
- {
- return static_cast<T*>(detail::get_tss_data(this));
- }
- T* operator->() const
- {
- return get();
- }
- T& operator*() const
- {
- return *get();
- }
- T* release()
- {
- T* const temp=get();
- detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false);
- return temp;
- }
- void reset(T* new_value=0)
- {
- T* const current_value=get();
- if(current_value!=new_value)
- {
- detail::set_tss_data(this,cleanup,new_value,true);
- }
- }
- };
-}
-
-
-#endif

Modified: branches/release/boost/thread/xtime.hpp
==============================================================================
--- branches/release/boost/thread/xtime.hpp (original)
+++ branches/release/boost/thread/xtime.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -1,6 +1,6 @@
 // Copyright (C) 2001-2003
 // William E. Kempf
-// Copyright (C) 2007 Anthony Williams
+// Copyright (C) 2007-8 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)
@@ -14,6 +14,8 @@
 #include <boost/thread/thread_time.hpp>
 #include <boost/date_time/posix_time/conversion.hpp>
 
+#include <boost/config/abi_prefix.hpp>
+
 namespace boost {
 
 enum xtime_clock_types
@@ -56,7 +58,7 @@
 
 inline xtime get_xtime(boost::system_time const& abs_time)
 {
- xtime res={0};
+ xtime res;
     boost::posix_time::time_duration const time_since_epoch=abs_time-boost::posix_time::from_time_t(0);
             
     res.sec=static_cast<xtime::xtime_sec_t>(time_since_epoch.total_seconds());
@@ -85,4 +87,6 @@
 
 } // namespace boost
 
+#include <boost/config/abi_suffix.hpp>
+
 #endif //BOOST_XTIME_WEK070601_HPP

Modified: branches/release/boost/utility/addressof.hpp
==============================================================================
--- branches/release/boost/utility/addressof.hpp (original)
+++ branches/release/boost/utility/addressof.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -1,6 +1,7 @@
 // Copyright (C) 2002 Brad King (brad.king_at_[hidden])
 // Douglas Gregor (gregod_at_[hidden])
-// Peter Dimov
+//
+// Copyright (C) 2002, 2008 Peter Dimov
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -14,27 +15,31 @@
 # include <boost/config.hpp>
 # include <boost/detail/workaround.hpp>
 
-namespace boost {
-
-// Do not make addressof() inline. Breaks MSVC 7. (Peter Dimov)
+namespace boost
+{
 
-// VC7 strips const from nested classes unless we add indirection here
-# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
+namespace detail
+{
 
-template<class T> struct _addp
+template<class T> struct addressof_impl
 {
- typedef T * type;
+ static inline T * f( T & v, long )
+ {
+ return reinterpret_cast<T*>(
+ &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
+ }
+
+ static inline T * f( T * v, int )
+ {
+ return v;
+ }
 };
-
-template <typename T> typename _addp<T>::type
 
-# else
-template <typename T> T*
-# endif
-addressof(T& v)
+} // namespace detail
+
+template<class T> T * addressof( T & v )
 {
- return reinterpret_cast<T*>(
- &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
+ return boost::detail::addressof_impl<T>::f( v, 0 );
 }
 
 // Borland doesn't like casting an array reference to a char reference
@@ -53,6 +58,6 @@
 }
 # endif
 
-}
+} // namespace boost
 
 #endif // BOOST_UTILITY_ADDRESSOF_HPP

Modified: branches/release/libs/bind/bind.html
==============================================================================
--- branches/release/libs/bind/bind.html (original)
+++ branches/release/libs/bind/bind.html 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -60,6 +60,7 @@
                 <h4 style="MARGIN-LEFT: 40pt"><A href="#err_long_form">Inappropriate use of
                                 bind&lt;R&gt;(f, ...)</A></h4>
                 <h4 style="MARGIN-LEFT: 40pt">Binding a nonstandard function</h4>
+ <h4 style="MARGIN-LEFT: 40pt">Binding an overloaded function</h4>
                 <h4 style="MARGIN-LEFT: 40pt">const in signatures</h4>
                 <h4 style="MARGIN-LEFT: 40pt"><A href="#err_msvc_using">MSVC specific: using
                                 boost::bind;</A></h4>
@@ -188,6 +189,27 @@
 </pre>
                 <p>[Note: the ability to omit the return type is not available on all compilers.]
                 </p>
+ <P>By default, <STRONG>bind</STRONG> makes a copy of the provided function object. <code>
+ boost::ref</code> and <code>boost::cref</code> can be used to make it store
+ a reference to the function object, rather than a copy. This can be useful when
+ the function object is noncopyable, expensive to copy, or contains state; of
+ course, in this case the programmer is expected to ensure that the function
+ object is not destroyed while it's still being used.</P>
+ <pre>struct F2
+{
+ int s;
+
+ typedef void result_type;
+ void operator()( int x ) { s += x; }
+};
+
+F2 f2 = { 0 };
+int a[] = { 1, 2, 3 };
+
+std::for_each( a, a+3, bind( ref(f2), _1 ) );
+
+assert( f2.s == 6 );
+</pre>
                 <h3><a name="with_member_pointers">Using bind with pointers to members</a></h3>
                 <p>Pointers to member functions and pointers to data members are not function
                         objects, because they do not support <tt>operator()</tt>. For convenience, <b>bind</b>
@@ -285,21 +307,23 @@
                         evaluation, use <tt>protect(bind(f, ...))</tt>.</P>
                 <h3><a name="operators">Overloaded operators</a> (new in Boost 1.33)</h3>
                 <p>For convenience, the function objects produced by <tt>bind</tt> overload the
- logical not operator <STRONG>!</STRONG> and the relational operators <STRONG>==</STRONG>,
- <STRONG>!=</STRONG>, <STRONG>&lt;</STRONG>, <STRONG>&lt;=</STRONG>, <STRONG>&gt;</STRONG>,
- <STRONG>&gt;=</STRONG>.</p>
+ logical not operator <code>!</code> and the relational and logical operators <code>==</code>,
+ <code>!=</code>, <code>&lt;</code>, <code>&lt;=</code>, <code>&gt;</code>, <code>&gt;=</code>,
+ <code>&amp;&amp;</code>, <code>||</code>.</p>
                 <P><tt>!bind(f, ...)</tt> is equivalent to <tt>bind( <EM>logical_not</EM>(), bind(f,
                                 ...) )</tt>, where <tt><EM>logical_not</EM></tt> is a function object that
                         takes one argument <tt>x</tt> and returns <tt>!x</tt>.</P>
- <P><tt>bind(f, ...) <EM>op</EM> x</tt>, where <EM>op</EM> is a relational operator,
- is equivalent to <tt>bind( <EM>relation</EM>(), bind(f, ...), x )</tt>, where <em>relation</em>
- is a function object that takes two arguments <tt>a</tt> and <tt>b</tt> and
- returns <tt>a <EM>op</EM> b</tt>.</P>
+ <P><tt>bind(f, ...) <EM>op</EM> x</tt>, where <EM>op</EM> is a relational or
+ logical operator, is equivalent to <tt>bind( <EM>relation</EM>(), bind(f, ...), x )</tt>,
+ where <em>relation</em> is a function object that takes two arguments <tt>a</tt>
+ and <tt>b</tt> and returns <tt>a <EM>op</EM> b</tt>.</P>
                 <P>What this means in practice is that you can conveniently negate the result of <tt>bind</tt>:</P>
                 <P><tt>std::remove_if( first, last, !bind( &amp;X::visible, _1 ) ); // remove invisible
                                 objects</tt></P>
                 <P>and compare the result of <tt>bind</tt> against a value:</P>
- <P><tt>std::find_if( first, last, bind( &amp;X::name, _1 ) == "peter" );</tt></P>
+ <P><tt>std::find_if( first, last, bind( &amp;X::name, _1 ) == "Peter" );</tt></P>
+ <P><tt>std::find_if( first, last, bind( &amp;X::name, _1 ) == "Peter" || bind(
+ &amp;X::name, _1 ) == "Paul" );</tt></P>
                 <P>against a placeholder:</P>
                 <P><tt>bind( &amp;X::name, _1 ) == _2</tt></P>
                 <P>or against another <tt>bind</tt> expression:</P>
@@ -362,10 +386,12 @@
 }
 </pre>
                 <h2><a name="Limitations">Limitations</a></h2>
- <p>The function objects generated by <b>bind</b> take their arguments by reference
- and cannot, therefore, accept non-const temporaries or literal constants. This
- is an inherent limitation of the C++ language, known as <A href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm">
- the forwarding problem</A>.</p>
+ <p>As a general rule, the function objects generated by <b>bind</b> take their
+ arguments by reference and cannot, therefore, accept non-const temporaries or
+ literal constants. This is an inherent limitation of the C++ language in its
+ current (2003) incarnation, known as <A href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm">
+ the forwarding problem</A>. (It will be fixed in the next standard, usually
+ called C++0x.)</p>
                 <p>The library uses signatures of the form
                 </p>
                 <pre>template&lt;class T&gt; void f(T &amp; t);
@@ -373,17 +399,17 @@
                 <p>to accept arguments of arbitrary types and pass them on unmodified. As noted,
                         this does not work with non-const r-values.
                 </p>
- <p>An oft-proposed "solution" to this problem is to add an overload:
+ <p>On compilers that support partial ordering of function templates, a possible
+ solution is to add an overload:
                 </p>
                 <pre>template&lt;class T&gt; void f(T &amp; t);
 template&lt;class T&gt; void f(T const &amp; t);
 </pre>
- <p>Unfortunately, this (a) requires providing 512 overloads for nine arguments and
- (b) does not actually work for const arguments, both l- and r-values, since the
- two templates produce the exact same signature and cannot be partially ordered.
- </p>
- <p>[Note: this is a dark corner of the language, and the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#214">
- corresponding issue</a> has only recently been resolved.]
+ <p>Unfortunately, this requires providing 512 overloads for nine arguments, which
+ is impractical. The library chooses a small subset: for up to two arguments, it
+ provides the const overloads in full, for arities of three and more it provides
+ a single additional overload with all of the arguments taken by const
+ reference. This covers a reasonable portion of the use cases.
                 </p>
                 <h2><a name="FAQ">Frequently Asked Questions</a></h2>
                 <h3><a name="Q_doesnt_compile">Why doesn't this compile?</a></h3>
@@ -528,6 +554,37 @@
                         recognized by the short form of bind.
                 </p>
                 <P>See also "__stdcall" and "pascal" Support.</P>
+ <h3><a name="err_overloaded">Binding an overloaded function</a></h3>
+ <p>An attempt to bind an overloaded function usually results in an error, as there
+ is no way to tell which overload was meant to be bound. This is a common
+ problem with member functions with two overloads, const and non-const, as in
+ this simplified example:</p>
+ <pre>struct X
+{
+ int&amp; get();
+ int const&amp; get() const;
+};
+
+int main()
+{
+ boost::bind( &amp;X::get, _1 );
+}
+</pre>
+ <P>The ambiguity can be resolved manually by casting the (member) function pointer
+ to the desired type:</P>
+<pre>int main()
+{
+ boost::bind( static_cast&lt; int const&amp; (X::*) () const &gt;( &amp;X::get ), _1 );
+}
+</pre>
+ <P>Another, arguably more readable, alternative is to introduce a temporary
+ variable:</P>
+<pre>int main()
+{
+ int const&amp; (X::*get) () const = &amp;X::get;
+ boost::bind( get, _1 );
+}
+</pre>
                 <h3><a name="err_const_arg"><b>const</b> in signatures</a></h3>
                 <p>Some compilers, including MSVC 6.0 and Borland C++ 5.5.1, have problems with the
                         top-level <b>const</b> in function signatures:
@@ -859,7 +916,7 @@
                         by Jaakko Järvi;
                         <li>
                                 The Lambda Library
- (now part of Boost) by Jaakko Järvi and Gary Powell (the successor to the
+ (now part of Boost) by Jaakko Järvi and Gary Powell (the successor to the
                         Binder Library);
                         <li>
                                 <a href="http://more.sourceforge.net/">Extensions to the STL</a> by Petter
@@ -890,7 +947,7 @@
                         <br>
                         <br>
                         <small>Copyright © 2001, 2002 by Peter Dimov and Multi Media Ltd. Copyright
- 2003-2005 Peter Dimov. Distributed under the Boost Software License, Version
+ 2003-2008 Peter Dimov. 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.</small></p>
         </body>

Modified: branches/release/libs/bind/test/Jamfile.v2
==============================================================================
--- branches/release/libs/bind/test/Jamfile.v2 (original)
+++ branches/release/libs/bind/test/Jamfile.v2 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -27,10 +27,15 @@
       [ run bind_visit_test.cpp ]
       [ run bind_placeholder_test.cpp ]
       [ run bind_rvalue_test.cpp ]
+ [ run bind_and_or_test.cpp ]
       [ run mem_fn_test.cpp ]
       [ run mem_fn_void_test.cpp ]
       [ run mem_fn_derived_test.cpp ]
       [ run mem_fn_eq_test.cpp ]
       [ run mem_fn_dm_test.cpp ]
       [ run mem_fn_rv_test.cpp ]
+ [ run ref_fn_test.cpp ]
+ [ run bind_fnobj2_test.cpp ]
+ [ run bind_fn2_test.cpp ]
+ [ run bind_mf2_test.cpp ]
     ;

Modified: branches/release/libs/bind/test/bind_lookup_problem_test.cpp
==============================================================================
--- branches/release/libs/bind/test/bind_lookup_problem_test.cpp (original)
+++ branches/release/libs/bind/test/bind_lookup_problem_test.cpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -1,7 +1,7 @@
 //
 // bind_lookup_problem_test.cpp
 //
-// Copyright (C) Markus Schöpflin 2005.
+// Copyright (C) Markus Schoepflin 2005.
 //
 // Use, modification, and distribution are subject to the Boost Software
 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/libs/thread/doc/changes.qbk
==============================================================================
--- branches/release/libs/thread/doc/changes.qbk (original)
+++ branches/release/libs/thread/doc/changes.qbk 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -44,7 +44,14 @@
 but did not lock it on construction. This facility has now been replaced with the constructor that takes a
 `boost::defer_lock_type` as the second parameter: ``boost::mutex::scoped_lock some_lock(some_mutex,boost::defer_lock);``
 
+* The `locked()` member function of the `scoped_lock` types has been renamed to __owns_lock_ref__.
+
+* You can no longer obtain a __thread__ instance representing the current thread: a default-constructed __thread__ object is not
+associated with any thread. The only use for such a thread object was to support the comparison operators: this functionality has
+been moved to __thread_id__.
+
 * The broken `boost::read_write_mutex` has been replaced with __shared_mutex__.
 
+* __mutex__ is now never recursive. For Boost releases prior to 1.35 __mutex__ was recursive on Windows and not on POSIX platforms.
 
 [endsect]

Modified: branches/release/libs/thread/doc/mutex_concepts.qbk
==============================================================================
--- branches/release/libs/thread/doc/mutex_concepts.qbk (original)
+++ branches/release/libs/thread/doc/mutex_concepts.qbk 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -373,6 +373,7 @@
     class unique_lock
     {
     public:
+ unique_lock();
         explicit unique_lock(Lockable& m_);
         unique_lock(Lockable& m_,adopt_lock_t);
         unique_lock(Lockable& m_,defer_lock_t);
@@ -426,6 +427,20 @@
 __lockable_concept_type__ object by a particular thread, and the member functions that release ownership of the lock state
 (including the destructor) must be called by the same thread that acquired ownership of the lock state.
 
+[section:defaultconstructor `unique_lock()`]
+
+[variablelist
+
+[[Effects:] [Creates a lock object with no associated mutex.]]
+
+[[Postcondition:] [__owns_lock_ref__ returns `false`. __mutex_func_ref__ returns `NULL`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
 [section:constructor `unique_lock(Lockable & m)`]
 
 [variablelist
@@ -599,6 +614,7 @@
     class shared_lock
     {
     public:
+ shared_lock();
         explicit shared_lock(Lockable& m_);
         shared_lock(Lockable& m_,adopt_lock_t);
         shared_lock(Lockable& m_,defer_lock_t);
@@ -644,6 +660,20 @@
 ownership of a __lockable_concept_type__ object by a particular thread, and the member functions that release ownership of the lock
 state (including the destructor) must be called by the same thread that acquired ownership of the lock state.
 
+[section:defaultconstructor `shared_lock()`]
+
+[variablelist
+
+[[Effects:] [Creates a lock object with no associated mutex.]]
+
+[[Postcondition:] [__owns_lock_ref__ returns `false`. __mutex_func_ref__ returns `NULL`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
 [section:constructor `shared_lock(Lockable & m)`]
 
 [variablelist

Modified: branches/release/libs/thread/doc/mutexes.qbk
==============================================================================
--- branches/release/libs/thread/doc/mutexes.qbk (original)
+++ branches/release/libs/thread/doc/mutexes.qbk 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -12,6 +12,9 @@
         void lock();
         bool try_lock();
         void unlock();
+
+ typedef platform-specific-type native_handle_type;
+ native_handle_type native_handle();
         
         typedef unique_lock<mutex> scoped_lock;
         typedef scoped_lock scoped_try_lock;
@@ -20,6 +23,23 @@
 __mutex__ implements the __lockable_concept__ to provide an exclusive-ownership mutex. At most one thread can own the lock on a given
 instance of __mutex__ at any time. Multiple concurrent calls to __lock_ref__, __try_lock_ref__ and __unlock_ref__ shall be permitted.
 
+[section:nativehandle Member function `native_handle()`]
+
+ typedef platform-specific-type native_handle_type;
+ native_handle_type native_handle();
+
+[variablelist
+
+[[Effects:] [Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying
+implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+
 [endsect]
 
 [section:try_mutex Typedef `try_mutex`]
@@ -47,6 +67,9 @@
         template<typename TimeDuration>
         bool timed_lock(TimeDuration const & relative_time);
 
+ typedef platform-specific-type native_handle_type;
+ native_handle_type native_handle();
+
         typedef unique_lock<timed_mutex> scoped_timed_lock;
         typedef scoped_timed_lock scoped_try_lock;
         typedef scoped_timed_lock scoped_lock;
@@ -56,6 +79,22 @@
 lock on a given instance of __timed_mutex__ at any time. Multiple concurrent calls to __lock_ref__, __try_lock_ref__,
 __timed_lock_ref__, __timed_lock_duration_ref__ and __unlock_ref__ shall be permitted.
 
+[section:nativehandle Member function `native_handle()`]
+
+ typedef platform-specific-type native_handle_type;
+ native_handle_type native_handle();
+
+[variablelist
+
+[[Effects:] [Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying
+implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
 [endsect]
 
 [section:recursive_mutex Class `recursive_mutex`]
@@ -70,6 +109,9 @@
         void lock();
         bool try_lock();
         void unlock();
+
+ typedef platform-specific-type native_handle_type;
+ native_handle_type native_handle();
         
         typedef unique_lock<recursive_mutex> scoped_lock;
         typedef scoped_lock scoped_try_lock;
@@ -81,6 +123,22 @@
 __lock_ref__ or __try_lock_ref__ to acquire an additional level of ownership of the mutex. __unlock_ref__ must be called once for
 each level of ownership acquired by a single thread before ownership can be acquired by another thread.
 
+[section:nativehandle Member function `native_handle()`]
+
+ typedef platform-specific-type native_handle_type;
+ native_handle_type native_handle();
+
+[variablelist
+
+[[Effects:] [Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying
+implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
 [endsect]
 
 [section:recursive_try_mutex Typedef `recursive_try_mutex`]
@@ -108,6 +166,9 @@
 
         template<typename TimeDuration>
         bool timed_lock(TimeDuration const & relative_time);
+
+ typedef platform-specific-type native_handle_type;
+ native_handle_type native_handle();
         
         typedef unique_lock<recursive_timed_mutex> scoped_lock;
         typedef scoped_lock scoped_try_lock;
@@ -121,6 +182,22 @@
 __timed_lock_duration_ref__ or __try_lock_ref__ to acquire an additional level of ownership of the mutex. __unlock_ref__ must be
 called once for each level of ownership acquired by a single thread before ownership can be acquired by another thread.
 
+[section:nativehandle Member function `native_handle()`]
+
+ typedef platform-specific-type native_handle_type;
+ native_handle_type native_handle();
+
+[variablelist
+
+[[Effects:] [Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying
+implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
 [endsect]
 
 [include shared_mutex_ref.qbk]

Modified: branches/release/libs/thread/doc/thread.qbk
==============================================================================
--- branches/release/libs/thread/doc/thread.qbk (original)
+++ branches/release/libs/thread/doc/thread.qbk 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -147,4 +147,6 @@
 
 [include tss.qbk]
 
+[include time.qbk]
+
 [include acknowledgements.qbk]

Modified: branches/release/libs/thread/doc/thread_ref.qbk
==============================================================================
--- branches/release/libs/thread/doc/thread_ref.qbk (original)
+++ branches/release/libs/thread/doc/thread_ref.qbk 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -17,6 +17,13 @@
         some_thread.join();
     }
 
+[Note: On compilers that support rvalue references, __thread__ provides a proper move constructor and move-assignment operator, and
+therefore meets the C++0x ['MoveConstructible] and ['MoveAssignable] concepts. With such compilers, __thread__ can therefore be used
+with containers that support those concepts.
+
+For other compilers, move support is provided with a move emulation layer, so containers must explicitly detect that move emulation
+layer. See <boost/thread/detail/move.hpp> for details.]
+
 [heading Launching threads]
 
 A new thread is launched by passing an object of a callable type that can be invoked with no parameters to the constructor. The
@@ -43,11 +50,21 @@
       // this leads to undefined behaviour
 
 If you wish to construct an instance of __thread__ with a function or callable object that requires arguments to be supplied,
-this can be done using `boost::bind`:
+this can be done by passing additional arguments to the __thread__ constructor:
 
     void find_the_question(int the_answer);
 
- boost::thread deep_thought_2(boost::bind(find_the_question,42));
+ boost::thread deep_thought_2(find_the_question,42);
+
+The arguments are ['copied] into the internal thread structure: if a reference is required, use `boost::ref`, just as for references
+to callable functions.
+
+There is an unspecified limit on the number of additional arguments that can be passed.
+
+[heading Exceptions in thread functions]
+
+If the function or callable object passed to the __thread__ constructor propagates an exception when invoked that is not of type
+__thread_interrupted__, `std::terminate()` is called.
 
 [heading Joining and detaching]
 
@@ -189,6 +206,8 @@
         static void sleep(const system_time& xt);
     };
 
+ void swap(thread& lhs,thread& rhs);
+
 [section:default_constructor Default Constructor]
 
     thread();
@@ -212,7 +231,9 @@
 
 [[Preconditions:] [`Callable` must by copyable.]]
 
-[[Effects:] [`func` is copied into storage managed internally by the thread library, and that copy is invoked on a newly-created thread of execution.]]
+[[Effects:] [`func` is copied into storage managed internally by the thread library, and that copy is invoked on a newly-created
+thread of execution. If this invocation results in an exception being propagated into the internals of the thread library that is
+not of type __thread_interrupted__, then `std::terminate()` will be called.]]
 
 [[Postconditions:] [`*this` refers to the newly created thread of execution.]]
 
@@ -306,7 +327,7 @@
 
 [variablelist
 
-[[Effects:] [If `*this` refers to a thread of execution, that thread of execution becomes detached, and longer has an associated __thread__ object.]]
+[[Effects:] [If `*this` refers to a thread of execution, that thread of execution becomes detached, and no longer has an associated __thread__ object.]]
 
 [[Postconditions:] [`*this` no longer refers to any thread of execution.]]
 
@@ -364,6 +385,22 @@
 
 [endsect]
 
+[section:nativehandle Member function `native_handle()`]
+
+ typedef platform-specific-type native_handle_type;
+ native_handle_type native_handle();
+
+[variablelist
+
+[[Effects:] [Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying
+implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
 [section:equals `operator==`]
 
     bool operator==(const thread& other) const;
@@ -416,6 +453,36 @@
 
 [endsect]
 
+[section:swap Member function `swap()`]
+
+ void swap(thread& other);
+
+[variablelist
+
+[[Effects:] [Exchanges the threads of execution associated with `*this` and `other`, so `*this` is associated with the thread of
+execution associated with `other` prior to the call, and vice-versa.]]
+
+[[Postconditions:] [`this->get_id()` returns the same value as `other.get_id()` prior to the call. `other.get_id()` returns the same
+value as `this->get_id()` prior to the call.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:non_member_swap Non-member function `swap()`]
+
+ void swap(thread& lhs,thread& rhs);
+
+[variablelist
+
+[[Effects:] [[link thread.thread_management.thread.swap `lhs.swap(rhs)`].]]
+
+]
+
+[endsect]
+
 
 [section:id Class `boost::thread::id`]
 
@@ -471,7 +538,7 @@
 
 [variablelist
 
-[[Returns:] [`true` if `*this` and `y` represent the different threads of execution, or one represents a thread of execution, and
+[[Returns:] [`true` if `*this` and `y` represent different threads of execution, or one represents a thread of execution, and
 the other represent __not_a_thread__, `false` otherwise.]]
 
 [[Throws:] [Nothing]]

Modified: branches/release/libs/thread/example/condition.cpp
==============================================================================
--- branches/release/libs/thread/example/condition.cpp (original)
+++ branches/release/libs/thread/example/condition.cpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -46,11 +46,16 @@
 
 bounded_buffer buf(2);
 
+boost::mutex io_mutex;
+
 void sender() {
     int n = 0;
     while (n < 100) {
         buf.send(n);
- std::cout << "sent: " << n << std::endl;
+ {
+ boost::mutex::scoped_lock io_lock(io_mutex);
+ std::cout << "sent: " << n << std::endl;
+ }
         ++n;
     }
     buf.send(-1);
@@ -60,7 +65,10 @@
     int n;
     do {
         n = buf.receive();
- std::cout << "received: " << n << std::endl;
+ {
+ boost::mutex::scoped_lock io_lock(io_mutex);
+ std::cout << "received: " << n << std::endl;
+ }
     } while (n != -1); // -1 indicates end of buffer
 }
 

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 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -1,6 +1,6 @@
 // Copyright (C) 2001-2003
 // William E. Kempf
-// Copyright (C) 2007 Anthony Williams
+// Copyright (C) 2007-8 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)
@@ -18,7 +18,7 @@
 #elif defined(__APPLE__) || defined(__FreeBSD__)
 #include <sys/types.h>
 #include <sys/sysctl.h>
-#elif defined(__sun)
+#elif defined(__sun) || defined(__CYGWIN__)
 #include <unistd.h>
 #endif
 
@@ -28,6 +28,9 @@
 {
     namespace detail
     {
+ thread_data_base::~thread_data_base()
+ {}
+
         struct thread_exit_callback_node
         {
             boost::detail::thread_exit_function_base* func;
@@ -119,7 +122,7 @@
         {
             void* thread_proxy(void* param)
             {
- boost::shared_ptr<boost::detail::thread_data_base> thread_info = static_cast<boost::detail::thread_data_base*>(param)->self;
+ boost::detail::thread_data_ptr thread_info = static_cast<boost::detail::thread_data_base*>(param)->self;
                 thread_info->self.reset();
                 detail::set_current_thread_data(thread_info.get());
                 try
@@ -153,6 +156,10 @@
             
             void run()
             {}
+
+ private:
+ externally_launched_thread(externally_launched_thread&);
+ void operator=(externally_launched_thread&);
         };
 
         detail::thread_data_base* make_external_thread_data()
@@ -196,47 +203,6 @@
         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();
- }
-
- bool thread::operator!=(const thread& other) const
- {
- return !operator==(other);
- }
-
     detail::thread_data_ptr thread::get_thread_info() const
     {
         lock_guard<mutex> l(thread_info_mutex);
@@ -361,57 +327,61 @@
         }
     }
 
- void thread::sleep(const system_time& st)
+ namespace this_thread
     {
- detail::thread_data_base* const thread_info=detail::get_current_thread_data();
         
- if(thread_info)
- {
- unique_lock<mutex> lk(thread_info->sleep_mutex);
- while(thread_info->sleep_condition.timed_wait(lk,st));
- }
- else
+ void sleep(const system_time& st)
         {
- xtime const xt=get_xtime(st);
-
- for (int foo=0; foo < 5; ++foo)
+ detail::thread_data_base* const thread_info=detail::get_current_thread_data();
+
+ if(thread_info)
+ {
+ unique_lock<mutex> lk(thread_info->sleep_mutex);
+ while(thread_info->sleep_condition.timed_wait(lk,st));
+ }
+ else
             {
+ xtime const xt=get_xtime(st);
+
+ for (int foo=0; foo < 5; ++foo)
+ {
 # if defined(BOOST_HAS_PTHREAD_DELAY_NP)
- timespec ts;
- to_timespec_duration(xt, ts);
- BOOST_VERIFY(!pthread_delay_np(&ts));
+ timespec ts;
+ to_timespec_duration(xt, ts);
+ BOOST_VERIFY(!pthread_delay_np(&ts));
 # elif defined(BOOST_HAS_NANOSLEEP)
- timespec ts;
- to_timespec_duration(xt, ts);
+ timespec ts;
+ to_timespec_duration(xt, ts);
                 
- // nanosleep takes a timespec that is an offset, not
- // an absolute time.
- nanosleep(&ts, 0);
+ // nanosleep takes a timespec that is an offset, not
+ // an absolute time.
+ nanosleep(&ts, 0);
 # else
- mutex mx;
- mutex::scoped_lock lock(mx);
- condition cond;
- cond.timed_wait(lock, xt);
+ mutex mx;
+ mutex::scoped_lock lock(mx);
+ condition cond;
+ cond.timed_wait(lock, xt);
 # endif
- xtime cur;
- xtime_get(&cur, TIME_UTC);
- if (xtime_cmp(xt, cur) <= 0)
- return;
+ xtime cur;
+ xtime_get(&cur, TIME_UTC);
+ if (xtime_cmp(xt, cur) <= 0)
+ return;
+ }
             }
         }
- }
 
- void thread::yield()
- {
+ void yield()
+ {
 # if defined(BOOST_HAS_SCHED_YIELD)
- BOOST_VERIFY(!sched_yield());
+ BOOST_VERIFY(!sched_yield());
 # elif defined(BOOST_HAS_PTHREAD_YIELD)
- BOOST_VERIFY(!pthread_yield());
+ BOOST_VERIFY(!pthread_yield());
 # else
- xtime xt;
- xtime_get(&xt, TIME_UTC);
- sleep(xt);
+ xtime xt;
+ xtime_get(&xt, TIME_UTC);
+ sleep(xt);
 # endif
+ }
     }
 
     unsigned thread::hardware_concurrency()
@@ -424,7 +394,7 @@
         int count;
         size_t size=sizeof(count);
         return sysctlbyname("hw.ncpu",&count,&size,NULL,0)?0:count;
-#elif defined(__sun)
+#elif defined(__sun) || defined(__CYGWIN__)
         int const count=sysconf(_SC_NPROCESSORS_ONLN);
         return (count>0)?count:0;
 #else
@@ -472,6 +442,21 @@
             return false;
         }
     }
+
+ thread::native_handle_type thread::native_handle()
+ {
+ detail::thread_data_ptr const local_thread_info=get_thread_info();
+ if(local_thread_info)
+ {
+ lock_guard<mutex> lk(local_thread_info->data_mutex);
+ return local_thread_info->thread_handle;
+ }
+ else
+ {
+ return pthread_t();
+ }
+ }
+
     
 
     namespace this_thread
@@ -607,85 +592,85 @@
         }
     }
 
- thread_group::thread_group()
- {
- }
-
- thread_group::~thread_group()
- {
- // We shouldn't have to scoped_lock here, since referencing this object
- // from another thread while we're deleting it in the current thread is
- // going to lead to undefined behavior any way.
- for (std::list<thread*>::iterator it = m_threads.begin();
- it != m_threads.end(); ++it)
- {
- delete (*it);
- }
- }
-
- thread* thread_group::create_thread(const function0<void>& threadfunc)
- {
- // No scoped_lock required here since the only "shared data" that's
- // modified here occurs inside add_thread which does scoped_lock.
- std::auto_ptr<thread> thrd(new thread(threadfunc));
- add_thread(thrd.get());
- return thrd.release();
- }
-
- void thread_group::add_thread(thread* thrd)
- {
- mutex::scoped_lock scoped_lock(m_mutex);
-
- // For now we'll simply ignore requests to add a thread object multiple
- // times. Should we consider this an error and either throw or return an
- // error value?
- std::list<thread*>::iterator it = std::find(m_threads.begin(),
- m_threads.end(), thrd);
- BOOST_ASSERT(it == m_threads.end());
- if (it == m_threads.end())
- m_threads.push_back(thrd);
- }
-
- void thread_group::remove_thread(thread* thrd)
- {
- mutex::scoped_lock scoped_lock(m_mutex);
-
- // For now we'll simply ignore requests to remove a thread object that's
- // not in the group. Should we consider this an error and either throw or
- // return an error value?
- std::list<thread*>::iterator it = std::find(m_threads.begin(),
- m_threads.end(), thrd);
- BOOST_ASSERT(it != m_threads.end());
- if (it != m_threads.end())
- m_threads.erase(it);
- }
-
- void thread_group::join_all()
- {
- mutex::scoped_lock scoped_lock(m_mutex);
- for (std::list<thread*>::iterator it = m_threads.begin();
- it != m_threads.end(); ++it)
- {
- (*it)->join();
- }
- }
-
- void thread_group::interrupt_all()
- {
- boost::lock_guard<mutex> guard(m_mutex);
+// thread_group::thread_group()
+// {
+// }
+
+// thread_group::~thread_group()
+// {
+// // We shouldn't have to scoped_lock here, since referencing this object
+// // from another thread while we're deleting it in the current thread is
+// // going to lead to undefined behavior any way.
+// for (std::list<thread*>::iterator it = m_threads.begin();
+// it != m_threads.end(); ++it)
+// {
+// delete (*it);
+// }
+// }
+
+// thread* thread_group::create_thread(const function0<void>& threadfunc)
+// {
+// // No scoped_lock required here since the only "shared data" that's
+// // modified here occurs inside add_thread which does scoped_lock.
+// std::auto_ptr<thread> thrd(new thread(threadfunc));
+// add_thread(thrd.get());
+// return thrd.release();
+// }
+
+// void thread_group::add_thread(thread* thrd)
+// {
+// mutex::scoped_lock scoped_lock(m_mutex);
+
+// // For now we'll simply ignore requests to add a thread object multiple
+// // times. Should we consider this an error and either throw or return an
+// // error value?
+// std::list<thread*>::iterator it = std::find(m_threads.begin(),
+// m_threads.end(), thrd);
+// BOOST_ASSERT(it == m_threads.end());
+// if (it == m_threads.end())
+// m_threads.push_back(thrd);
+// }
+
+// void thread_group::remove_thread(thread* thrd)
+// {
+// mutex::scoped_lock scoped_lock(m_mutex);
+
+// // For now we'll simply ignore requests to remove a thread object that's
+// // not in the group. Should we consider this an error and either throw or
+// // return an error value?
+// std::list<thread*>::iterator it = std::find(m_threads.begin(),
+// m_threads.end(), thrd);
+// BOOST_ASSERT(it != m_threads.end());
+// if (it != m_threads.end())
+// m_threads.erase(it);
+// }
+
+// void thread_group::join_all()
+// {
+// mutex::scoped_lock scoped_lock(m_mutex);
+// for (std::list<thread*>::iterator it = m_threads.begin();
+// it != m_threads.end(); ++it)
+// {
+// (*it)->join();
+// }
+// }
+
+// void thread_group::interrupt_all()
+// {
+// boost::lock_guard<mutex> guard(m_mutex);
             
- for(std::list<thread*>::iterator it=m_threads.begin(),end=m_threads.end();
- it!=end;
- ++it)
- {
- (*it)->interrupt();
- }
- }
+// for(std::list<thread*>::iterator it=m_threads.begin(),end=m_threads.end();
+// it!=end;
+// ++it)
+// {
+// (*it)->interrupt();
+// }
+// }
         
 
- size_t thread_group::size() const
- {
- return m_threads.size();
- }
+// size_t thread_group::size() const
+// {
+// return m_threads.size();
+// }
 
 }

Modified: branches/release/libs/thread/src/tss_null.cpp
==============================================================================
--- branches/release/libs/thread/src/tss_null.cpp (original)
+++ branches/release/libs/thread/src/tss_null.cpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -6,7 +6,7 @@
 
 #include <boost/thread/detail/config.hpp>
 
-#if defined(BOOST_HAS_WINTHREADS) && (defined(BOOST_THREAD_BUILD_LIB) || defined(BOOST_THREAD_TEST)) && (!defined(_MSC_VER) || defined(UNDER_CE))
+#if defined(BOOST_HAS_WINTHREADS) && (defined(BOOST_THREAD_BUILD_LIB) || defined(BOOST_THREAD_TEST) || defined(UNDER_CE)) && (!defined(_MSC_VER) || defined(UNDER_CE))
 
     /*
     This file is a "null" implementation of tss cleanup; it's

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 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -81,25 +81,6 @@
 
     }
 
- void thread::yield()
- {
- this_thread::yield();
- }
-
- void thread::sleep(const system_time& target)
- {
- system_time const now(get_system_time());
-
- if(target<=now)
- {
- this_thread::yield();
- }
- else
- {
- this_thread::sleep(target-now);
- }
- }
-
     namespace detail
     {
         struct thread_exit_callback_node
@@ -164,26 +145,24 @@
             set_current_thread_data(0);
         }
         
- }
-
-
- unsigned __stdcall thread::thread_start_function(void* param)
- {
- detail::thread_data_base* const thread_info(reinterpret_cast<detail::thread_data_base*>(param));
- set_current_thread_data(thread_info);
- try
+ unsigned __stdcall thread_start_function(void* param)
         {
- thread_info->run();
- }
- catch(thread_interrupted const&)
- {
- }
- catch(...)
- {
- std::terminate();
+ detail::thread_data_base* const thread_info(reinterpret_cast<detail::thread_data_base*>(param));
+ set_current_thread_data(thread_info);
+ try
+ {
+ thread_info->run();
+ }
+ catch(thread_interrupted const&)
+ {
+ }
+ catch(...)
+ {
+ std::terminate();
+ }
+ run_thread_exit_callbacks();
+ return 0;
         }
- run_thread_exit_callbacks();
- return 0;
     }
 
     thread::thread()
@@ -218,6 +197,9 @@
             
             void run()
             {}
+ private:
+ externally_launched_thread(externally_launched_thread&);
+ void operator=(externally_launched_thread&);
         };
 
         void make_external_thread_data()
@@ -244,36 +226,6 @@
         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=0;
- }
-
- 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);
- }
-
     thread::id thread::get_id() const
     {
         return thread::id(get_thread_info());

Modified: branches/release/libs/thread/test/Jamfile.v2
==============================================================================
--- branches/release/libs/thread/test/Jamfile.v2 (original)
+++ branches/release/libs/thread/test/Jamfile.v2 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -22,22 +22,24 @@
     : requirements <library>/boost/test//boost_unit_test_framework/<link>static
                    <threading>multi
     ;
-
+
 rule thread-run ( sources )
 {
     return
- [ run $(sources) ../build//boost_thread ]
- [ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
- : : : : $(sources[1]:B)_lib ]
- ;
+ [ run $(sources) ../build//boost_thread ]
+ [ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
+ : : : : $(sources[1]:B)_lib ]
+ ;
 }
-
+
 {
     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_thread_launching.cpp ]
+ [ thread-run test_thread_mf.cpp ]
           [ thread-run test_move_function.cpp ]
           [ thread-run test_mutex.cpp ]
           [ thread-run test_condition_notify_one.cpp ]
@@ -47,9 +49,13 @@
           [ thread-run test_tss.cpp ]
           [ thread-run test_once.cpp ]
           [ thread-run test_xtime.cpp ]
- [ thread-run test_barrier.cpp ]
+ [ thread-run test_barrier.cpp ]
           [ thread-run test_shared_mutex.cpp ]
           [ thread-run test_shared_mutex_part_2.cpp ]
+ [ thread-run test_shared_mutex_timed_locks.cpp ]
           [ thread-run test_lock_concept.cpp ]
+ [ thread-run test_generic_locks.cpp ]
+ [ compile-fail no_implicit_move_from_lvalue_thread.cpp ]
+ [ compile-fail no_implicit_assign_from_lvalue_thread.cpp ]
     ;
 }

Modified: branches/release/libs/thread/test/shared_mutex_locking_thread.hpp
==============================================================================
--- branches/release/libs/thread/test/shared_mutex_locking_thread.hpp (original)
+++ branches/release/libs/thread/test/shared_mutex_locking_thread.hpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -66,5 +66,67 @@
     void operator=(locking_thread&);
 };
 
+class simple_writing_thread
+{
+ boost::shared_mutex& rwm;
+ boost::mutex& finish_mutex;
+ boost::mutex& unblocked_mutex;
+ unsigned& unblocked_count;
+
+ void operator=(simple_writing_thread&);
+
+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);
+ }
+};
+
+class simple_reading_thread
+{
+ boost::shared_mutex& rwm;
+ boost::mutex& finish_mutex;
+ boost::mutex& unblocked_mutex;
+ unsigned& unblocked_count;
+
+ void operator=(simple_reading_thread&);
+
+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);
+ }
+};
+
 
 #endif

Modified: branches/release/libs/thread/test/test_condition_notify_all.cpp
==============================================================================
--- branches/release/libs/thread/test/test_condition_notify_all.cpp (original)
+++ branches/release/libs/thread/test/test_condition_notify_all.cpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -159,6 +159,47 @@
     }
 }
 
+namespace
+{
+ boost::mutex multiple_wake_mutex;
+ boost::condition_variable multiple_wake_cond;
+ unsigned multiple_wake_count=0;
+
+ void wait_for_condvar_and_increase_count()
+ {
+ boost::mutex::scoped_lock lk(multiple_wake_mutex);
+ multiple_wake_cond.wait(lk);
+ ++multiple_wake_count;
+ }
+
+}
+
+
+void do_test_notify_all_following_notify_one_wakes_all_threads()
+{
+ boost::thread thread1(wait_for_condvar_and_increase_count);
+ boost::thread thread2(wait_for_condvar_and_increase_count);
+
+ boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+ multiple_wake_cond.notify_one();
+
+ boost::thread thread3(wait_for_condvar_and_increase_count);
+
+ boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+ multiple_wake_cond.notify_one();
+ multiple_wake_cond.notify_all();
+ boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+
+ {
+ boost::mutex::scoped_lock lk(multiple_wake_mutex);
+ BOOST_CHECK(multiple_wake_count==3);
+ }
+
+ thread1.join();
+ thread2.join();
+ thread3.join();
+}
+
 void test_condition_notify_all()
 {
     timed_test(&do_test_condition_notify_all_wakes_from_wait, timeout_seconds);
@@ -166,6 +207,7 @@
     timed_test(&do_test_condition_notify_all_wakes_from_timed_wait, timeout_seconds);
     timed_test(&do_test_condition_notify_all_wakes_from_timed_wait_with_predicate, timeout_seconds);
     timed_test(&do_test_condition_notify_all_wakes_from_relative_timed_wait_with_predicate, timeout_seconds);
+ timed_test(&do_test_notify_all_following_notify_one_wakes_all_threads, timeout_seconds);
 }
 
 

Modified: branches/release/libs/thread/test/test_condition_notify_one.cpp
==============================================================================
--- branches/release/libs/thread/test/test_condition_notify_one.cpp (original)
+++ branches/release/libs/thread/test/test_condition_notify_one.cpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -92,6 +92,47 @@
     BOOST_CHECK(data.woken);
 }
 
+namespace
+{
+ boost::mutex multiple_wake_mutex;
+ boost::condition_variable multiple_wake_cond;
+ unsigned multiple_wake_count=0;
+
+ void wait_for_condvar_and_increase_count()
+ {
+ boost::mutex::scoped_lock lk(multiple_wake_mutex);
+ multiple_wake_cond.wait(lk);
+ ++multiple_wake_count;
+ }
+
+}
+
+
+void do_test_multiple_notify_one_calls_wakes_multiple_threads()
+{
+ boost::thread thread1(wait_for_condvar_and_increase_count);
+ boost::thread thread2(wait_for_condvar_and_increase_count);
+
+ boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+ multiple_wake_cond.notify_one();
+
+ boost::thread thread3(wait_for_condvar_and_increase_count);
+
+ boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+ multiple_wake_cond.notify_one();
+ multiple_wake_cond.notify_one();
+ boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+
+ {
+ boost::mutex::scoped_lock lk(multiple_wake_mutex);
+ BOOST_CHECK(multiple_wake_count==3);
+ }
+
+ thread1.join();
+ thread2.join();
+ thread3.join();
+}
+
 void test_condition_notify_one()
 {
     timed_test(&do_test_condition_notify_one_wakes_from_wait, timeout_seconds, execution_monitor::use_mutex);
@@ -99,6 +140,7 @@
     timed_test(&do_test_condition_notify_one_wakes_from_timed_wait, timeout_seconds, execution_monitor::use_mutex);
     timed_test(&do_test_condition_notify_one_wakes_from_timed_wait_with_predicate, timeout_seconds, execution_monitor::use_mutex);
     timed_test(&do_test_condition_notify_one_wakes_from_relative_timed_wait_with_predicate, timeout_seconds, execution_monitor::use_mutex);
+ timed_test(&do_test_multiple_notify_one_calls_wakes_multiple_threads, timeout_seconds, execution_monitor::use_mutex);
 }
 
 

Modified: branches/release/libs/thread/test/test_lock_concept.cpp
==============================================================================
--- branches/release/libs/thread/test/test_lock_concept.cpp (original)
+++ branches/release/libs/thread/test/test_lock_concept.cpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -1,4 +1,4 @@
-// (C) Copyright 2006-7 Anthony Williams
+// (C) Copyright 2006-8 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)
@@ -7,7 +7,9 @@
 #include <boost/test/test_case_template.hpp>
 #include <boost/mpl/vector.hpp>
 #include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
 #include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
 
 template<typename Mutex,typename Lock>
 struct test_initially_locked
@@ -23,6 +25,64 @@
 };
 
 template<typename Mutex,typename Lock>
+struct test_initially_unlocked_if_other_thread_has_lock
+{
+ Mutex m;
+ boost::mutex done_mutex;
+ bool done;
+ bool locked;
+ boost::condition_variable done_cond;
+
+ test_initially_unlocked_if_other_thread_has_lock():
+ done(false),locked(false)
+ {}
+
+ void locking_thread()
+ {
+ Lock lock(m);
+
+ boost::lock_guard<boost::mutex> lk(done_mutex);
+ locked=lock.owns_lock();
+ done=true;
+ done_cond.notify_one();
+ }
+
+ bool is_done() const
+ {
+ return done;
+ }
+
+
+ void operator()()
+ {
+ Lock lock(m);
+
+ typedef test_initially_unlocked_if_other_thread_has_lock<Mutex,Lock> this_type;
+
+ boost::thread t(&this_type::locking_thread,this);
+
+ try
+ {
+ {
+ boost::mutex::scoped_lock lk(done_mutex);
+ BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
+ boost::bind(&this_type::is_done,this)));
+ BOOST_CHECK(!locked);
+ }
+
+ lock.unlock();
+ t.join();
+ }
+ catch(...)
+ {
+ lock.unlock();
+ t.join();
+ throw;
+ }
+ }
+};
+
+template<typename Mutex,typename Lock>
 struct test_initially_unlocked_with_defer_lock_parameter
 {
     void operator()() const
@@ -125,11 +185,51 @@
         BOOST_CHECK_THROW( lock.unlock(), boost::lock_error );
     }
 };
+template<typename Lock>
+struct test_default_constructed_has_no_mutex_and_unlocked
+{
+ void operator()() const
+ {
+ Lock l;
+ BOOST_CHECK(!l.mutex());
+ BOOST_CHECK(!l.owns_lock());
+ };
+};
+
+
+template<typename Mutex,typename Lock>
+struct test_locks_can_be_swapped
+{
+ void operator()() const
+ {
+ Mutex m1;
+ Mutex m2;
+ Lock l1(m1);
+ Lock l2(m2);
+
+ BOOST_CHECK_EQUAL(l1.mutex(),&m1);
+ BOOST_CHECK_EQUAL(l2.mutex(),&m2);
+
+ l1.swap(l2);
+
+ BOOST_CHECK_EQUAL(l1.mutex(),&m2);
+ BOOST_CHECK_EQUAL(l2.mutex(),&m1);
+
+ swap(l1,l2);
+
+ BOOST_CHECK_EQUAL(l1.mutex(),&m1);
+ BOOST_CHECK_EQUAL(l2.mutex(),&m2);
+
+ }
+};
+
+
 
 BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_scoped_lock_concept,Mutex)
 {
     typedef typename Mutex::scoped_lock Lock;
     
+ test_default_constructed_has_no_mutex_and_unlocked<Lock>()();
     test_initially_locked<Mutex,Lock>()();
     test_initially_unlocked_with_defer_lock_parameter<Mutex,Lock>()();
     test_initially_locked_with_adopt_lock_parameter<Mutex,Lock>()();
@@ -137,13 +237,16 @@
     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>()();
+ test_locks_can_be_swapped<Mutex,Lock>()();
 }
 
 BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_scoped_try_lock_concept,Mutex)
 {
     typedef typename Mutex::scoped_try_lock Lock;
     
+ test_default_constructed_has_no_mutex_and_unlocked<Lock>()();
     test_initially_locked<Mutex,Lock>()();
+ test_initially_unlocked_if_other_thread_has_lock<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>()();
@@ -152,6 +255,7 @@
     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>()();
+ test_locks_can_be_swapped<Mutex,Lock>()();
 }
 
 boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])

Modified: branches/release/libs/thread/test/test_move_function.cpp
==============================================================================
--- branches/release/libs/thread/test/test_move_function.cpp (original)
+++ branches/release/libs/thread/test/test_move_function.cpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -1,10 +1,11 @@
-// Copyright (C) 2007 Anthony Williams
+// Copyright (C) 2007-8 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/thread.hpp>
 #include <boost/test/unit_test.hpp>
 #include <boost/thread/mutex.hpp>
+#include <boost/shared_ptr.hpp>
 
 void do_nothing()
 {}
@@ -20,13 +21,36 @@
     dest.join();
 }
 
+void test_thread_move_from_lvalue_on_assignment()
+{
+ boost::thread src(do_nothing);
+ boost::thread::id src_id=src.get_id();
+ boost::thread dest;
+ dest=boost::move(src);
+ boost::thread::id dest_id=dest.get_id();
+ BOOST_CHECK(src_id==dest_id);
+ BOOST_CHECK(src.get_id()==boost::thread::id());
+ dest.join();
+}
+
+boost::thread start_thread()
+{
+ return boost::thread(do_nothing);
+}
+
 void test_thread_move_from_rvalue_on_construction()
 {
- boost::thread x(boost::move(boost::thread(do_nothing)));
+ boost::thread x(start_thread());
     BOOST_CHECK(x.get_id()!=boost::thread::id());
     x.join();
 }
 
+void test_thread_move_from_rvalue_using_explicit_move()
+{
+ boost::thread x(boost::move(start_thread()));
+ BOOST_CHECK(x.get_id()!=boost::thread::id());
+ x.join();
+}
 
 void test_unique_lock_move_from_lvalue_on_construction()
 {
@@ -42,6 +66,48 @@
     BOOST_CHECK(l2.mutex()==&m);
 }
 
+boost::unique_lock<boost::mutex> get_lock(boost::mutex& m)
+{
+ return boost::unique_lock<boost::mutex>(m);
+}
+
+
+void test_unique_lock_move_from_rvalue_on_construction()
+{
+ boost::mutex m;
+ boost::unique_lock<boost::mutex> l(get_lock(m));
+ BOOST_CHECK(l.owns_lock());
+ BOOST_CHECK(l.mutex()==&m);
+}
+
+namespace user_test_ns
+{
+ template<typename T>
+ T move(T& t)
+ {
+ return t.move();
+ }
+
+ bool move_called=false;
+
+ struct nc:
+ public boost::shared_ptr<int>
+ {
+ nc move()
+ {
+ move_called=true;
+ return nc();
+ }
+ };
+}
+
+void test_move_for_user_defined_type_unaffected()
+{
+ user_test_ns::nc src;
+ user_test_ns::nc dest=move(src);
+ BOOST_CHECK(user_test_ns::move_called);
+}
+
 boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
 {
     boost::unit_test_framework::test_suite* test =
@@ -49,6 +115,10 @@
 
     test->add(BOOST_TEST_CASE(test_thread_move_from_lvalue_on_construction));
     test->add(BOOST_TEST_CASE(test_thread_move_from_rvalue_on_construction));
+ test->add(BOOST_TEST_CASE(test_thread_move_from_rvalue_using_explicit_move));
+ test->add(BOOST_TEST_CASE(test_thread_move_from_lvalue_on_assignment));
     test->add(BOOST_TEST_CASE(test_unique_lock_move_from_lvalue_on_construction));
+ test->add(BOOST_TEST_CASE(test_unique_lock_move_from_rvalue_on_construction));
+ test->add(BOOST_TEST_CASE(test_move_for_user_defined_type_unaffected));
     return test;
 }

Modified: branches/release/libs/thread/test/test_shared_mutex_part_2.cpp
==============================================================================
--- branches/release/libs/thread/test/test_shared_mutex_part_2.cpp (original)
+++ branches/release/libs/thread/test/test_shared_mutex_part_2.cpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -107,40 +107,6 @@
     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;
-
- void operator=(simple_writing_thread&);
-
- 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()
 {
 
@@ -175,40 +141,6 @@
     }
 }
 
-namespace
-{
- class simple_reading_thread
- {
- boost::shared_mutex& rwm;
- boost::mutex& finish_mutex;
- boost::mutex& unblocked_mutex;
- unsigned& unblocked_count;
-
- void operator=(simple_reading_thread&);
-
- 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()
 {
 
@@ -232,33 +164,6 @@
     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);
- boost::posix_time::milliseconds const timeout_resolution(20);
- bool const timed_lock_succeeded=rw_mutex.timed_lock_shared(timeout);
- BOOST_CHECK((timeout-timeout_resolution)<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 =
@@ -269,7 +174,6 @@
     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_thread.cpp
==============================================================================
--- branches/release/libs/thread/test/test_thread.cpp (original)
+++ branches/release/libs/thread/test/test_thread.cpp 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -1,5 +1,6 @@
 // Copyright (C) 2001-2003
 // William E. Kempf
+// Copyright (C) 2008 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)
@@ -198,6 +199,22 @@
     timed_test(&do_test_timed_join, 10);
 }
 
+void test_swap()
+{
+ boost::thread t(simple_thread);
+ boost::thread t2(simple_thread);
+ boost::thread::id id1=t.get_id();
+ boost::thread::id id2=t2.get_id();
+
+ t.swap(t2);
+ BOOST_CHECK(t.get_id()==id2);
+ BOOST_CHECK(t2.get_id()==id1);
+
+ swap(t,t2);
+ BOOST_CHECK(t.get_id()==id1);
+ BOOST_CHECK(t2.get_id()==id2);
+}
+
 
 boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
 {
@@ -211,6 +228,7 @@
     test->add(BOOST_TEST_CASE(test_thread_no_interrupt_if_interrupts_disabled_at_interruption_point));
     test->add(BOOST_TEST_CASE(test_creation_through_reference_wrapper));
     test->add(BOOST_TEST_CASE(test_timed_join));
+ test->add(BOOST_TEST_CASE(test_swap));
 
     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 2008-06-18 09:01:08 EDT (Wed, 18 Jun 2008)
@@ -258,11 +258,58 @@
     }
 }
 
+struct dummy_class_tracks_deletions
+{
+ static unsigned deletions;
+
+ ~dummy_class_tracks_deletions()
+ {
+ ++deletions;
+ }
+
+};
+
+unsigned dummy_class_tracks_deletions::deletions=0;
+
+boost::thread_specific_ptr<dummy_class_tracks_deletions> tss_with_null_cleanup(NULL);
+
+void tss_thread_with_null_cleanup(dummy_class_tracks_deletions* delete_tracker)
+{
+ tss_with_null_cleanup.reset(delete_tracker);
+}
+
+void do_test_tss_does_no_cleanup_with_null_cleanup_function()
+{
+ dummy_class_tracks_deletions* delete_tracker=new dummy_class_tracks_deletions;
+ boost::thread t(tss_thread_with_null_cleanup,delete_tracker);
+ try
+ {
+ t.join();
+ }
+ catch(...)
+ {
+ t.interrupt();
+ t.join();
+ throw;
+ }
+
+ BOOST_CHECK(!dummy_class_tracks_deletions::deletions);
+ if(!dummy_class_tracks_deletions::deletions)
+ {
+ delete delete_tracker;
+ }
+}
+
 void test_tss_does_no_cleanup_after_release()
 {
     timed_test(&do_test_tss_does_no_cleanup_after_release, 2);
 }
 
+void test_tss_does_no_cleanup_with_null_cleanup_function()
+{
+ timed_test(&do_test_tss_does_no_cleanup_with_null_cleanup_function, 2);
+}
+
 boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
 {
     boost::unit_test_framework::test_suite* test =
@@ -271,6 +318,7 @@
     test->add(BOOST_TEST_CASE(test_tss));
     test->add(BOOST_TEST_CASE(test_tss_with_custom_cleanup));
     test->add(BOOST_TEST_CASE(test_tss_does_no_cleanup_after_release));
+ test->add(BOOST_TEST_CASE(test_tss_does_no_cleanup_with_null_cleanup_function));
 
     return test;
 }


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