Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r63789 - in branches/release: boost boost/thread boost/thread/detail boost/thread/pthread boost/thread/win32 libs/thread libs/thread/build libs/thread/doc libs/thread/src/pthread libs/thread/src/win32 libs/thread/test
From: anthony_at_[hidden]
Date: 2010-07-09 15:13:12


Author: anthonyw
Date: 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
New Revision: 63789
URL: http://svn.boost.org/trac/boost/changeset/63789

Log:
Merged boost.thread changes over from trunk
Properties modified:
   branches/release/boost/thread/ (props changed)
   branches/release/boost/thread.hpp (props changed)
   branches/release/libs/thread/ (props changed)
Text files modified:
   branches/release/boost/thread/detail/config.hpp | 8 +
   branches/release/boost/thread/detail/platform.hpp | 2
   branches/release/boost/thread/detail/thread.hpp | 43 ++++++++-
   branches/release/boost/thread/detail/thread_group.hpp | 7 +
   branches/release/boost/thread/detail/tss_hooks.hpp | 33 +-----
   branches/release/boost/thread/future.hpp | 22 +++-
   branches/release/boost/thread/locks.hpp | 170 ++++++++++++++++++++++++++++++++++-----
   branches/release/boost/thread/pthread/condition_variable.hpp | 6
   branches/release/boost/thread/pthread/condition_variable_fwd.hpp | 3
   branches/release/boost/thread/pthread/mutex.hpp | 23 ++++-
   branches/release/boost/thread/pthread/recursive_mutex.hpp | 97 ++++++++++++++++++++--
   branches/release/boost/thread/pthread/shared_mutex.hpp | 2
   branches/release/boost/thread/tss.hpp | 2
   branches/release/boost/thread/win32/mutex.hpp | 8 +
   branches/release/boost/thread/win32/recursive_mutex.hpp | 8 +
   branches/release/boost/thread/win32/shared_mutex.hpp | 67 ++++++++++++---
   branches/release/boost/thread/win32/thread_data.hpp | 7 +
   branches/release/libs/thread/build/Jamfile.v2 | 1
   branches/release/libs/thread/doc/thread_ref.qbk | 60 +++++++++++++
   branches/release/libs/thread/src/pthread/thread.cpp | 34 +++----
   branches/release/libs/thread/src/win32/thread.cpp | 64 +++++++++-----
   branches/release/libs/thread/src/win32/tss_dll.cpp | 18 ++-
   branches/release/libs/thread/src/win32/tss_pe.cpp | 67 ++++++--------
   branches/release/libs/thread/test/test_futures.cpp | 4
   branches/release/libs/thread/test/test_generic_locks.cpp | 77 +++++++++++++++++
   branches/release/libs/thread/test/test_shared_mutex_part_2.cpp | 9 ++
   26 files changed, 638 insertions(+), 204 deletions(-)

Modified: branches/release/boost/thread/detail/config.hpp
==============================================================================
--- branches/release/boost/thread/detail/config.hpp (original)
+++ branches/release/boost/thread/detail/config.hpp 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -19,8 +19,14 @@
 
 #include "platform.hpp"
 
+// provided for backwards compatibility, since this
+// macro was used for several releases by mistake.
+#if defined(BOOST_THREAD_DYN_DLL)
+# define BOOST_THREAD_DYN_LINK
+#endif
+
 // compatibility with the rest of Boost's auto-linking code:
-#if defined(BOOST_THREAD_DYN_DLL) || defined(BOOST_ALL_DYN_LINK)
+#if defined(BOOST_THREAD_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
 # undef BOOST_THREAD_USE_LIB
 # define BOOST_THREAD_USE_DLL
 #endif

Modified: branches/release/boost/thread/detail/platform.hpp
==============================================================================
--- branches/release/boost/thread/detail/platform.hpp (original)
+++ branches/release/boost/thread/detail/platform.hpp 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -29,7 +29,7 @@
 # define BOOST_THREAD_HPUX
 #elif defined(__CYGWIN__)
 # define BOOST_THREAD_CYGWIN
-#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+#elif (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && !defined(BOOST_DISABLE_WIN32)
 # define BOOST_THREAD_WIN32
 #elif defined(__BEOS__)
 # define BOOST_THREAD_BEOS

Modified: branches/release/boost/thread/detail/thread.hpp
==============================================================================
--- branches/release/boost/thread/detail/thread.hpp (original)
+++ branches/release/boost/thread/detail/thread.hpp 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -3,10 +3,12 @@
 // 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-8 Anthony Williams
+// (C) Copyright 2007-10 Anthony Williams
  
 #include <boost/thread/exceptions.hpp>
+#ifndef BOOST_NO_IOSTREAM
 #include <ostream>
+#endif
 #include <boost/thread/detail/move.hpp>
 #include <boost/thread/mutex.hpp>
 #include <boost/thread/xtime.hpp>
@@ -113,14 +115,13 @@
 
         void release_handle();
         
- 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;
+ detail::thread_data_ptr get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const;
 
 #ifndef BOOST_NO_RVALUE_REFERENCES
         template<typename F>
@@ -147,7 +148,7 @@
 #endif
         struct dummy;
     public:
-#ifdef __SUNPRO_CC
+#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
         thread(const volatile thread&);
 #endif
         thread();
@@ -157,7 +158,7 @@
 #ifdef BOOST_MSVC
         template <class F>
         explicit thread(F f,typename disable_if<boost::is_convertible<F&,detail::thread_move_t<F> >, dummy* >::type=0):
- thread_info(make_thread_info(f))
+ thread_info(make_thread_info(static_cast<F&&>(f)))
         {
             start_thread();
         }
@@ -217,7 +218,7 @@
             x->thread_info.reset();
         }
        
-#ifdef __SUNPRO_CC
+#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
         thread& operator=(thread x)
         {
             swap(x);
@@ -394,7 +395,7 @@
             thread_data(thread_data_)
         {}
         friend class thread;
- friend id this_thread::get_id();
+ friend id BOOST_THREAD_DECL this_thread::get_id();
     public:
         id():
             thread_data()
@@ -430,6 +431,8 @@
             return !(thread_data<y.thread_data);
         }
 
+#ifndef BOOST_NO_IOSTREAM
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
         template<class charT, class traits>
         friend std::basic_ostream<charT, traits>&
         operator<<(std::basic_ostream<charT, traits>& os, const id& x)
@@ -443,8 +446,34 @@
                 return os<<"{Not-any-thread}";
             }
         }
+#else
+ template<class charT, class traits>
+ std::basic_ostream<charT, traits>&
+ print(std::basic_ostream<charT, traits>& os)
+ {
+ if(thread_data)
+ {
+ return os<<thread_data;
+ }
+ else
+ {
+ return os<<"{Not-any-thread}";
+ }
+ }
+
+#endif
+#endif
     };
 
+#if !defined(BOOST_NO_IOSTREAM) && defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
+ template<class charT, class traits>
+ std::basic_ostream<charT, traits>&
+ operator<<(std::basic_ostream<charT, traits>& os, const thread::id& x)
+ {
+ return x.print(os);
+ }
+#endif
+
     inline bool thread::operator==(const thread& other) const
     {
         return get_id()==other.get_id();

Modified: branches/release/boost/thread/detail/thread_group.hpp
==============================================================================
--- branches/release/boost/thread/detail/thread_group.hpp (original)
+++ branches/release/boost/thread/detail/thread_group.hpp 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -18,10 +18,13 @@
 
 namespace boost
 {
- class thread_group:
- private noncopyable
+ class thread_group
     {
+ private:
+ thread_group(thread_group const&);
+ thread_group& operator=(thread_group const&);
     public:
+ thread_group() {}
         ~thread_group()
         {
             for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();

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 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -12,27 +12,9 @@
 
 #if defined(BOOST_HAS_WINTHREADS)
 
- typedef void (__cdecl *thread_exit_handler)(void);
-
- extern "C" BOOST_THREAD_DECL int at_thread_exit(
- thread_exit_handler exit_handler
- );
- //Add a function to the list of functions that will
- //be called when a thread is about to exit.
- //Currently only implemented for Win32, but should
- //later be implemented for all platforms.
- //Used by Win32 implementation of Boost.Threads
- //tss to perform cleanup.
- //Like the C runtime library atexit() function,
- //which it mimics, at_thread_exit() returns
- //zero if successful and a nonzero
- //value if an error occurs.
-
-#endif //defined(BOOST_HAS_WINTHREADS)
-
-#if defined(BOOST_HAS_WINTHREADS)
-
- extern "C" BOOST_THREAD_DECL void on_process_enter(void);
+namespace boost
+{
+ BOOST_THREAD_DECL void __cdecl on_process_enter(void);
         //Function to be called when the exe or dll
             //that uses Boost.Threads first starts
             //or is first loaded.
@@ -42,7 +24,7 @@
             //a method for doing so has been discovered.
         //May be omitted; may be called multiple times.
 
- extern "C" BOOST_THREAD_DECL void on_process_exit(void);
+ BOOST_THREAD_DECL void __cdecl on_process_exit(void);
         //Function to be called when the exe or dll
             //that uses Boost.Threads first starts
             //or is first loaded.
@@ -52,7 +34,7 @@
             //a method for doing so has been discovered.
         //Must not be omitted; may be called multiple times.
 
- extern "C" BOOST_THREAD_DECL void on_thread_enter(void);
+ BOOST_THREAD_DECL void __cdecl on_thread_enter(void);
         //Function to be called just after a thread starts
             //in an exe or dll that uses Boost.Threads.
         //Must be called in the context of the thread
@@ -61,7 +43,7 @@
             //a method for doing so has been discovered.
         //May be omitted; may be called multiple times.
 
- extern "C" BOOST_THREAD_DECL void __cdecl on_thread_exit(void);
+ 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
@@ -70,10 +52,11 @@
             //a method for doing so has been discovered.
         //Must not be omitted; may be called multiple times.
     
- extern "C" void tss_cleanup_implemented(void);
+ void tss_cleanup_implemented();
         //Dummy function used both to detect whether tss cleanup
             //cleanup has been implemented and to force
             //it to be linked into the Boost.Threads library.
+}
 
 #endif //defined(BOOST_HAS_WINTHREADS)
 

Modified: branches/release/boost/thread/future.hpp
==============================================================================
--- branches/release/boost/thread/future.hpp (original)
+++ branches/release/boost/thread/future.hpp 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -9,6 +9,8 @@
 #include <stdexcept>
 #include <boost/thread/detail/move.hpp>
 #include <boost/thread/thread_time.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
 #include <boost/exception_ptr.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/scoped_ptr.hpp>
@@ -140,6 +142,8 @@
                 {
                     lock.lock();
                 }
+ private:
+ relocker& operator=(relocker const&);
             };
 
             void do_callback(boost::unique_lock<boost::mutex>& lock)
@@ -388,15 +392,18 @@
 
         class future_waiter
         {
+ struct registered_waiter;
+ typedef std::vector<registered_waiter>::size_type count_type;
+
             struct registered_waiter
             {
                 boost::shared_ptr<detail::future_object_base> future;
                 detail::future_object_base::waiter_list::iterator wait_iterator;
- unsigned index;
+ count_type index;
 
                 registered_waiter(boost::shared_ptr<detail::future_object_base> const& future_,
                                   detail::future_object_base::waiter_list::iterator wait_iterator_,
- unsigned index_):
+ count_type index_):
                     future(future_),wait_iterator(wait_iterator_),index(index_)
                 {}
 
@@ -404,7 +411,6 @@
             
             struct all_futures_lock
             {
- typedef std::vector<registered_waiter>::size_type count_type;
                 count_type count;
                 boost::scoped_array<boost::unique_lock<boost::mutex> > locks;
                 
@@ -424,7 +430,7 @@
                 
                 void unlock()
                 {
- for(unsigned i=0;i<count;++i)
+ for(count_type i=0;i<count;++i)
                     {
                         locks[i].unlock();
                     }
@@ -433,7 +439,7 @@
             
             boost::condition_variable_any cv;
             std::vector<registered_waiter> futures;
- unsigned future_count;
+ count_type future_count;
             
         public:
             future_waiter():
@@ -450,12 +456,12 @@
                 ++future_count;
             }
 
- unsigned wait()
+ count_type wait()
             {
                 all_futures_lock lk(futures);
                 for(;;)
                 {
- for(unsigned i=0;i<futures.size();++i)
+ for(count_type i=0;i<futures.size();++i)
                     {
                         if(futures[i].future->done)
                         {
@@ -468,7 +474,7 @@
             
             ~future_waiter()
             {
- for(unsigned i=0;i<futures.size();++i)
+ for(count_type i=0;i<futures.size();++i)
                 {
                     futures[i].future->remove_external_waiter(futures[i].wait_iterator);
                 }

Modified: branches/release/boost/thread/locks.hpp
==============================================================================
--- branches/release/boost/thread/locks.hpp (original)
+++ branches/release/boost/thread/locks.hpp 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -11,6 +11,7 @@
 #include <iterator>
 #include <boost/thread/thread_time.hpp>
 #include <boost/detail/workaround.hpp>
+#include <boost/type_traits/is_class.hpp>
 
 #include <boost/config/abi_prefix.hpp>
 
@@ -27,41 +28,101 @@
 #ifndef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
     namespace detail
     {
- template<typename T>
+#define BOOST_DEFINE_HAS_MEMBER_CALLED(member_name) \
+ template<typename T, bool=boost::is_class<T>::value> \
+ struct has_member_called_##member_name \
+ { \
+ BOOST_STATIC_CONSTANT(bool, value=false); \
+ }; \
+ \
+ template<typename T> \
+ struct has_member_called_##member_name<T,true> \
+ { \
+ typedef char true_type; \
+ struct false_type \
+ { \
+ true_type dummy[2]; \
+ }; \
+ \
+ struct fallback { int member_name; }; \
+ struct derived: \
+ T, fallback \
+ { \
+ derived(); \
+ }; \
+ \
+ template<int fallback::*> struct tester; \
+ \
+ template<typename U> \
+ static false_type has_member(tester<&U::member_name>*); \
+ template<typename U> \
+ static true_type has_member(...); \
+ \
+ BOOST_STATIC_CONSTANT( \
+ bool, value=sizeof(has_member<derived>(0))==sizeof(true_type)); \
+ }
+
+ BOOST_DEFINE_HAS_MEMBER_CALLED(lock);
+ BOOST_DEFINE_HAS_MEMBER_CALLED(unlock);
+ BOOST_DEFINE_HAS_MEMBER_CALLED(try_lock);
+
+ template<typename T,bool=has_member_called_lock<T>::value >
         struct has_member_lock
         {
+ BOOST_STATIC_CONSTANT(bool, value=false);
+ };
+
+ template<typename T>
+ struct has_member_lock<T,true>
+ {
             typedef char true_type;
             struct false_type
             {
                 true_type dummy[2];
             };
             
+ template<typename U,typename V>
+ static true_type has_member(V (U::*)());
             template<typename U>
- static true_type has_member(U*,void (U::*dummy)()=&U::lock);
- static false_type has_member(void*);
+ static false_type has_member(U);
             
- BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_lock<T>::has_member((T*)NULL))==sizeof(true_type));
+ BOOST_STATIC_CONSTANT(
+ bool,value=sizeof(has_member_lock<T>::has_member(&T::lock))==sizeof(true_type));
         };
-
- template<typename T>
+
+ template<typename T,bool=has_member_called_unlock<T>::value >
         struct has_member_unlock
         {
+ BOOST_STATIC_CONSTANT(bool, value=false);
+ };
+
+ template<typename T>
+ struct has_member_unlock<T,true>
+ {
             typedef char true_type;
             struct false_type
             {
                 true_type dummy[2];
             };
             
+ template<typename U,typename V>
+ static true_type has_member(V (U::*)());
             template<typename U>
- static true_type has_member(U*,void (U::*dummy)()=&U::unlock);
- static false_type has_member(void*);
+ static false_type has_member(U);
             
- BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_unlock<T>::has_member((T*)NULL))==sizeof(true_type));
+ BOOST_STATIC_CONSTANT(
+ bool,value=sizeof(has_member_unlock<T>::has_member(&T::unlock))==sizeof(true_type));
         };
         
- template<typename T>
+ template<typename T,bool=has_member_called_try_lock<T>::value >
         struct has_member_try_lock
         {
+ BOOST_STATIC_CONSTANT(bool, value=false);
+ };
+
+ template<typename T>
+ struct has_member_try_lock<T,true>
+ {
             typedef char true_type;
             struct false_type
             {
@@ -69,10 +130,12 @@
             };
             
             template<typename U>
- static true_type has_member(U*,bool (U::*dummy)()=&U::try_lock);
- static false_type has_member(void*);
+ static true_type has_member(bool (U::*)());
+ template<typename U>
+ static false_type has_member(U);
             
- BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_try_lock<T>::has_member((T*)NULL))==sizeof(true_type));
+ BOOST_STATIC_CONSTANT(
+ bool,value=sizeof(has_member_try_lock<T>::has_member(&T::try_lock))==sizeof(true_type));
         };
 
     }
@@ -214,7 +277,7 @@
         unique_lock& operator=(unique_lock&);
         unique_lock& operator=(upgrade_lock<Mutex>& other);
     public:
-#ifdef __SUNPRO_CC
+#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
         unique_lock(const volatile unique_lock&);
 #endif
         unique_lock():
@@ -300,7 +363,7 @@
             return detail::thread_move_t<unique_lock<Mutex> >(*this);
         }
 
-#ifdef __SUNPRO_CC
+#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
         unique_lock& operator=(unique_lock<Mutex> other)
         {
             swap(other);
@@ -422,6 +485,18 @@
     {
         lhs.swap(rhs);
     }
+
+ template<typename Mutex>
+ inline upgrade_lock<Mutex>&& move(upgrade_lock<Mutex>&& ul)
+ {
+ return static_cast<upgrade_lock<Mutex>&&>(ul);
+ }
+
+ template<typename Mutex>
+ inline upgrade_lock<Mutex>&& move(upgrade_lock<Mutex>& ul)
+ {
+ return static_cast<upgrade_lock<Mutex>&&>(ul);
+ }
 #endif
     template<typename Mutex>
     void swap(unique_lock<Mutex>& lhs,unique_lock<Mutex>& rhs)
@@ -678,6 +753,39 @@
         {
             try_lock();
         }
+#ifdef BOOST_HAS_RVALUE_REFS
+ upgrade_lock(upgrade_lock<Mutex>&& other):
+ m(other.m),is_locked(other.is_locked)
+ {
+ other.is_locked=false;
+ other.m=0;
+ }
+
+ upgrade_lock(unique_lock<Mutex>&& other):
+ m(other.m),is_locked(other.is_locked)
+ {
+ if(is_locked)
+ {
+ m->unlock_and_lock_upgrade();
+ }
+ other.is_locked=false;
+ other.m=0;
+ }
+
+ upgrade_lock& operator=(upgrade_lock<Mutex>&& other)
+ {
+ upgrade_lock temp(static_cast<upgrade_lock<Mutex>&&>(other));
+ swap(temp);
+ return *this;
+ }
+
+ upgrade_lock& operator=(unique_lock<Mutex>&& other)
+ {
+ upgrade_lock temp(static_cast<unique_lock<Mutex>&&>(other));
+ swap(temp);
+ return *this;
+ }
+#else
         upgrade_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
             m(other->m),is_locked(other->is_locked)
         {
@@ -720,6 +828,7 @@
             swap(temp);
             return *this;
         }
+#endif
 
         void swap(upgrade_lock& other)
         {
@@ -824,6 +933,20 @@
             }
         }
 
+#ifdef BOOST_HAS_RVALUE_REFS
+ upgrade_to_unique_lock(upgrade_to_unique_lock<Mutex>&& other):
+ source(other.source),exclusive(move(other.exclusive))
+ {
+ other.source=0;
+ }
+
+ upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Mutex>&& other)
+ {
+ upgrade_to_unique_lock temp(other);
+ swap(temp);
+ return *this;
+ }
+#else
         upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other):
             source(other->source),exclusive(move(other->exclusive))
         {
@@ -836,6 +959,7 @@
             swap(temp);
             return *this;
         }
+#endif
         void swap(upgrade_to_unique_lock& other)
         {
             std::swap(source,other.source);
@@ -923,15 +1047,15 @@
                 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);
             }
 #endif
+ void swap(try_lock_wrapper& other)
+ {
+ base::swap(other);
+ }
             void lock()
             {
                 base::lock();
@@ -1116,7 +1240,7 @@
         {
             unsigned const lock_count=2;
             unsigned lock_first=0;
- while(true)
+ for(;;)
             {
                 switch(lock_first)
                 {
@@ -1169,7 +1293,7 @@
     {
         unsigned const lock_count=3;
         unsigned lock_first=0;
- while(true)
+ for(;;)
         {
             switch(lock_first)
             {
@@ -1201,7 +1325,7 @@
     {
         unsigned const lock_count=4;
         unsigned lock_first=0;
- while(true)
+ for(;;)
         {
             switch(lock_first)
             {
@@ -1239,7 +1363,7 @@
     {
         unsigned const lock_count=5;
         unsigned lock_first=0;
- while(true)
+ for(;;)
         {
             switch(lock_first)
             {

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 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -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-8 Anthony Williams
+// (C) Copyright 2007-10 Anthony Williams
 
 #include "timespec.hpp"
 #include "pthread_mutex_scoped_lock.hpp"
@@ -48,8 +48,8 @@
         pthread_mutex_t internal_mutex;
         pthread_cond_t cond;
 
- condition_variable_any(condition_variable&);
- condition_variable_any& operator=(condition_variable&);
+ condition_variable_any(condition_variable_any&);
+ condition_variable_any& operator=(condition_variable_any&);
 
     public:
         condition_variable_any()

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 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -47,7 +47,8 @@
             while(!pred()) wait(m);
         }
 
- bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until);
+ inline bool timed_wait(unique_lock<mutex>& m,
+ boost::system_time const& wait_until);
         bool timed_wait(unique_lock<mutex>& m,xtime const& wait_until)
         {
             return timed_wait(m,system_time(wait_until));

Modified: branches/release/boost/thread/pthread/mutex.hpp
==============================================================================
--- branches/release/boost/thread/pthread/mutex.hpp (original)
+++ branches/release/boost/thread/pthread/mutex.hpp 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -27,10 +27,11 @@
 
 namespace boost
 {
- class mutex:
- boost::noncopyable
+ class mutex
     {
     private:
+ mutex(mutex const&);
+ mutex& operator=(mutex const&);
         pthread_mutex_t m;
     public:
         mutex()
@@ -48,7 +49,11 @@
         
         void lock()
         {
- BOOST_VERIFY(!pthread_mutex_lock(&m));
+ int const res=pthread_mutex_lock(&m);
+ if(res)
+ {
+ boost::throw_exception(lock_error(res));
+ }
         }
 
         void unlock()
@@ -59,7 +64,11 @@
         bool try_lock()
         {
             int const res=pthread_mutex_trylock(&m);
- BOOST_ASSERT(!res || res==EBUSY);
+ if(res && (res!=EBUSY))
+ {
+ boost::throw_exception(lock_error(res));
+ }
+
             return !res;
         }
 
@@ -75,10 +84,12 @@
 
     typedef mutex try_mutex;
 
- class timed_mutex:
- boost::noncopyable
+ class timed_mutex
     {
     private:
+ timed_mutex(timed_mutex const&);
+ timed_mutex& operator=(timed_mutex const&);
+ private:
         pthread_mutex_t m;
 #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
         pthread_cond_t cond;

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 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -26,18 +26,30 @@
 #endif
 #endif
 
+#if defined(BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE) && defined(BOOST_PTHREAD_HAS_TIMEDLOCK)
+#define BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
+#endif
+
 #include <boost/config/abi_prefix.hpp>
 
 namespace boost
 {
- class recursive_mutex:
- boost::noncopyable
+ class recursive_mutex
     {
     private:
+ recursive_mutex(recursive_mutex const&);
+ recursive_mutex& operator=(recursive_mutex const&);
         pthread_mutex_t m;
+#ifndef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE
+ pthread_cond_t cond;
+ bool is_locked;
+ pthread_t owner;
+ unsigned count;
+#endif
     public:
         recursive_mutex()
         {
+#ifdef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE
             pthread_mutexattr_t attr;
             
             int const init_attr_res=pthread_mutexattr_init(&attr);
@@ -54,15 +66,35 @@
             int const res=pthread_mutex_init(&m,&attr);
             if(res)
             {
+ BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
                 boost::throw_exception(thread_resource_error());
             }
             BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
+#else
+ int const res=pthread_mutex_init(&m,NULL);
+ if(res)
+ {
+ boost::throw_exception(thread_resource_error());
+ }
+ int const res2=pthread_cond_init(&cond,NULL);
+ if(res2)
+ {
+ BOOST_VERIFY(!pthread_mutex_destroy(&m));
+ boost::throw_exception(thread_resource_error());
+ }
+ is_locked=false;
+ count=0;
+#endif
         }
         ~recursive_mutex()
         {
             BOOST_VERIFY(!pthread_mutex_destroy(&m));
+#ifndef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE
+ BOOST_VERIFY(!pthread_cond_destroy(&cond));
+#endif
         }
-
+
+#ifdef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE
         void lock()
         {
             BOOST_VERIFY(!pthread_mutex_lock(&m));
@@ -79,25 +111,70 @@
             BOOST_ASSERT(!res || res==EBUSY);
             return !res;
         }
-
         typedef pthread_mutex_t* native_handle_type;
         native_handle_type native_handle()
         {
             return &m;
         }
 
+#else
+ void lock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(is_locked && pthread_equal(owner,pthread_self()))
+ {
+ ++count;
+ return;
+ }
+
+ while(is_locked)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
+ }
+ is_locked=true;
+ ++count;
+ owner=pthread_self();
+ }
+
+ void unlock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(!--count)
+ {
+ is_locked=false;
+ }
+ BOOST_VERIFY(!pthread_cond_signal(&cond));
+ }
+
+ bool try_lock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(is_locked && !pthread_equal(owner,pthread_self()))
+ {
+ return false;
+ }
+ is_locked=true;
+ ++count;
+ owner=pthread_self();
+ return true;
+ }
+
+#endif
+
         typedef unique_lock<recursive_mutex> scoped_lock;
         typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock;
     };
 
     typedef recursive_mutex recursive_try_mutex;
 
- class recursive_timed_mutex:
- boost::noncopyable
+ class recursive_timed_mutex
     {
     private:
+ recursive_timed_mutex(recursive_timed_mutex const&);
+ recursive_timed_mutex& operator=(recursive_timed_mutex const&);
+ private:
         pthread_mutex_t m;
-#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
+#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
         pthread_cond_t cond;
         bool is_locked;
         pthread_t owner;
@@ -106,7 +183,7 @@
     public:
         recursive_timed_mutex()
         {
-#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
+#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
             pthread_mutexattr_t attr;
             
             int const init_attr_res=pthread_mutexattr_init(&attr);
@@ -146,7 +223,7 @@
         ~recursive_timed_mutex()
         {
             BOOST_VERIFY(!pthread_mutex_destroy(&m));
-#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
+#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
             BOOST_VERIFY(!pthread_cond_destroy(&cond));
 #endif
         }
@@ -157,7 +234,7 @@
             return timed_lock(get_system_time()+relative_time);
         }
 
-#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
+#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
         void lock()
         {
             BOOST_VERIFY(!pthread_mutex_lock(&m));

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 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -225,7 +225,7 @@
         template<typename TimeDuration>
         bool timed_lock_upgrade(TimeDuration const & relative_time)
         {
- return timed_lock(get_system_time()+relative_time);
+ return timed_lock_upgrade(get_system_time()+relative_time);
         }
 
         bool try_lock_upgrade()

Modified: branches/release/boost/thread/tss.hpp
==============================================================================
--- branches/release/boost/thread/tss.hpp (original)
+++ branches/release/boost/thread/tss.hpp 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -62,6 +62,8 @@
         boost::shared_ptr<detail::tss_cleanup_function> cleanup;
         
     public:
+ typedef T element_type;
+
         thread_specific_ptr():
             cleanup(detail::heap_new<delete_data>(),detail::do_heap_delete<delete_data>())
         {}

Modified: branches/release/boost/thread/win32/mutex.hpp
==============================================================================
--- branches/release/boost/thread/win32/mutex.hpp (original)
+++ branches/release/boost/thread/win32/mutex.hpp 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -20,9 +20,11 @@
     }
 
     class mutex:
- boost::noncopyable,
         public ::boost::detail::underlying_mutex
     {
+ private:
+ mutex(mutex const&);
+ mutex& operator=(mutex const&);
     public:
         mutex()
         {
@@ -40,9 +42,11 @@
     typedef mutex try_mutex;
 
     class timed_mutex:
- boost::noncopyable,
         public ::boost::detail::basic_timed_mutex
     {
+ private:
+ timed_mutex(timed_mutex const&);
+ timed_mutex& operator=(timed_mutex const&);
     public:
         timed_mutex()
         {

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 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -20,9 +20,11 @@
 namespace boost
 {
     class recursive_mutex:
- boost::noncopyable,
         public ::boost::detail::basic_recursive_mutex
     {
+ private:
+ recursive_mutex(recursive_mutex const&);
+ recursive_mutex& operator=(recursive_mutex const&);
     public:
         recursive_mutex()
         {
@@ -40,9 +42,11 @@
     typedef recursive_mutex recursive_try_mutex;
 
     class recursive_timed_mutex:
- boost::noncopyable,
         public ::boost::detail::basic_recursive_timed_mutex
     {
+ private:
+ recursive_timed_mutex(recursive_timed_mutex const&);
+ recursive_timed_mutex& operator=(recursive_timed_mutex const&);
     public:
         recursive_timed_mutex()
         {

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 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -19,10 +19,12 @@
 
 namespace boost
 {
- class shared_mutex:
- private boost::noncopyable
+ class shared_mutex
     {
     private:
+ shared_mutex(shared_mutex const&);
+ shared_mutex& operator=(shared_mutex const&);
+ private:
         struct state_data
         {
             unsigned shared_count:11,
@@ -49,33 +51,35 @@
             return *reinterpret_cast<T const*>(&res);
         }
 
+ enum
+ {
+ unlock_sem = 0,
+ exclusive_sem = 1
+ };
+
         state_data state;
         detail::win32::handle semaphores[2];
- detail::win32::handle &unlock_sem;
- detail::win32::handle &exclusive_sem;
         detail::win32::handle upgrade_sem;
 
         void release_waiters(state_data old_state)
         {
             if(old_state.exclusive_waiting)
             {
- BOOST_VERIFY(detail::win32::ReleaseSemaphore(exclusive_sem,1,0)!=0);
+ BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[exclusive_sem],1,0)!=0);
             }
                         
             if(old_state.shared_waiting || old_state.exclusive_waiting)
             {
- BOOST_VERIFY(detail::win32::ReleaseSemaphore(unlock_sem,old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
+ BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
             }
         }
         
 
     public:
- shared_mutex():
- unlock_sem(semaphores[0]),
- exclusive_sem(semaphores[1])
+ shared_mutex()
         {
- unlock_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
- exclusive_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+ semaphores[unlock_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+ semaphores[exclusive_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
             upgrade_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
             state_data state_={0};
             state=state_;
@@ -84,8 +88,8 @@
         ~shared_mutex()
         {
             detail::win32::CloseHandle(upgrade_sem);
- detail::win32::CloseHandle(unlock_sem);
- detail::win32::CloseHandle(exclusive_sem);
+ detail::win32::CloseHandle(semaphores[unlock_sem]);
+ detail::win32::CloseHandle(semaphores[exclusive_sem]);
         }
 
         bool try_lock_shared()
@@ -97,6 +101,10 @@
                 if(!new_state.exclusive && !new_state.exclusive_waiting_blocked)
                 {
                     ++new_state.shared_count;
+ if(!new_state.shared_count)
+ {
+ return false;
+ }
                 }
                 
                 state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
@@ -131,10 +139,18 @@
                     if(new_state.exclusive || new_state.exclusive_waiting_blocked)
                     {
                         ++new_state.shared_waiting;
+ if(!new_state.shared_waiting)
+ {
+ boost::throw_exception(boost::lock_error());
+ }
                     }
                     else
                     {
                         ++new_state.shared_count;
+ if(!new_state.shared_count)
+ {
+ boost::throw_exception(boost::lock_error());
+ }
                     }
 
                     state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
@@ -150,7 +166,7 @@
                     return true;
                 }
                     
- unsigned long const res=detail::win32::WaitForSingleObject(unlock_sem,::boost::detail::get_milliseconds_until(wait_until));
+ unsigned long const res=detail::win32::WaitForSingleObject(semaphores[unlock_sem],::boost::detail::get_milliseconds_until(wait_until));
                 if(res==detail::win32::timeout)
                 {
                     for(;;)
@@ -166,6 +182,10 @@
                         else
                         {
                             ++new_state.shared_count;
+ if(!new_state.shared_count)
+ {
+ return false;
+ }
                         }
 
                         state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
@@ -282,6 +302,11 @@
                     if(new_state.shared_count || new_state.exclusive)
                     {
                         ++new_state.exclusive_waiting;
+ if(!new_state.exclusive_waiting)
+ {
+ boost::throw_exception(boost::lock_error());
+ }
+
                         new_state.exclusive_waiting_blocked=true;
                     }
                     else
@@ -374,10 +399,18 @@
                     if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
                     {
                         ++new_state.shared_waiting;
+ if(!new_state.shared_waiting)
+ {
+ boost::throw_exception(boost::lock_error());
+ }
                     }
                     else
                     {
                         ++new_state.shared_count;
+ if(!new_state.shared_count)
+ {
+ boost::throw_exception(boost::lock_error());
+ }
                         new_state.upgrade=true;
                     }
 
@@ -394,7 +427,7 @@
                     return;
                 }
                     
- BOOST_VERIFY(!detail::win32::WaitForSingleObject(unlock_sem,detail::win32::infinite));
+ BOOST_VERIFY(!detail::win32::WaitForSingleObject(semaphores[unlock_sem],detail::win32::infinite));
             }
         }
 
@@ -411,6 +444,10 @@
                 else
                 {
                     ++new_state.shared_count;
+ if(!new_state.shared_count)
+ {
+ return false;
+ }
                     new_state.upgrade=true;
                 }
                 

Modified: branches/release/boost/thread/win32/thread_data.hpp
==============================================================================
--- branches/release/boost/thread/win32/thread_data.hpp (original)
+++ branches/release/boost/thread/win32/thread_data.hpp 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -144,6 +144,11 @@
                 start(0),milliseconds(~uintmax_t(0)),relative(true)
             {}
         };
+
+ inline unsigned long pin_to_zero(long value)
+ {
+ return (value<0)?0u:(unsigned long)value;
+ }
     }
 
     namespace this_thread
@@ -163,7 +168,7 @@
         template<typename TimeDuration>
         inline void sleep(TimeDuration const& rel_time)
         {
- interruptible_wait(static_cast<unsigned long>(rel_time.total_milliseconds()));
+ interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds()));
         }
         inline void sleep(system_time const& abs_time)
         {

Modified: branches/release/libs/thread/build/Jamfile.v2
==============================================================================
--- branches/release/libs/thread/build/Jamfile.v2 (original)
+++ branches/release/libs/thread/build/Jamfile.v2 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -43,6 +43,7 @@
       <link>shared:<define>BOOST_THREAD_BUILD_DLL=1
       -<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
       <tag>@$(__name__).tag
+ <toolset>gcc:<cxxflags>-Wno-long-long
     : default-build <threading>multi
     ;
 

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 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -219,6 +219,7 @@
     };
 
     void swap(thread& lhs,thread& rhs);
+ detail::thread_move_t<thread> move(detail::thread_move_t<thread> t);
 
 [section:default_constructor Default Constructor]
 
@@ -234,6 +235,40 @@
 
 [endsect]
 
+[section:move_constructor Move Constructor]
+
+ thread(detail::thread_move_t<thread> other);
+
+[variablelist
+
+[[Effects:] [Transfers ownership of the thread managed by `other` (if any) to the newly constructed __thread__ instance.]]
+
+[[Postconditions:] [`other->get_id()==thread::id()`]]
+
+[[Throws:] [Nothing]]
+
+]
+
+[endsect]
+
+[section:move_assignment Move assignment operator]
+
+ thread& operator=(detail::thread_move_t<thread> other);
+
+[variablelist
+
+[[Effects:] [Transfers ownership of the thread managed by `other` (if
+any) to `*this`. If there was a thread previously associated with
+`*this` then that thread is detached.]]
+
+[[Postconditions:] [`other->get_id()==thread::id()`]]
+
+[[Throws:] [Nothing]]
+
+]
+
+[endsect]
+
 [section:callable_constructor Thread Constructor]
 
     template<typename Callable>
@@ -521,6 +556,26 @@
 
 [endsect]
 
+[section:non_member_move Non-member function `move()`]
+
+ #include <boost/thread/thread.hpp>
+
+ detail::thread_move_t<thread> move(detail::thread_move_t<thread> t)
+
+[variablelist
+
+[[Returns:] [`t`.]]
+
+]
+
+Enables moving thread objects. e.g.
+
+ extern void some_func();
+ boost::thread t(some_func);
+ boost::thread t2(boost::move(t)); // transfer thread from t to t2
+
+[endsect]
+
 
 [section:id Class `boost::thread::id`]
 
@@ -756,11 +811,14 @@
     {
         template<typename TimeDuration>
         void sleep(TimeDuration const& rel_time);
+ void sleep(system_time const& abs_time)
     }
 
 [variablelist
 
-[[Effects:] [Suspends the current thread until the specified time has elapsed.]]
+[[Effects:] [Suspends the current thread until the time period
+specified by `rel_time` has elapsed or the time point specified by
+`abs_time` has been reached.]]
 
 [[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted.]]
 

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 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -75,7 +75,7 @@
                             {
                                 current=next;
                                 ++next;
- if(current->second.func && current->second.value)
+ if(current->second.func && (current->second.value!=0))
                                 {
                                     (*current->second.func)(current->second.value);
                                 }
@@ -196,15 +196,14 @@
         detach();
     }
 
- detail::thread_data_ptr thread::get_thread_info() const
+ detail::thread_data_ptr thread::get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const
     {
- lock_guard<mutex> l(thread_info_mutex);
         return thread_info;
     }
 
     void thread::join()
     {
- detail::thread_data_ptr const local_thread_info=get_thread_info();
+ detail::thread_data_ptr const local_thread_info=(get_thread_info)();
         if(local_thread_info)
         {
             bool do_join=false;
@@ -238,7 +237,6 @@
                 local_thread_info->done_condition.notify_all();
             }
             
- lock_guard<mutex> l1(thread_info_mutex);
             if(thread_info==local_thread_info)
             {
                 thread_info.reset();
@@ -248,7 +246,7 @@
 
     bool thread::timed_join(system_time const& wait_until)
     {
- detail::thread_data_ptr const local_thread_info=get_thread_info();
+ detail::thread_data_ptr const local_thread_info=(get_thread_info)();
         if(local_thread_info)
         {
             bool do_join=false;
@@ -285,7 +283,6 @@
                 local_thread_info->done_condition.notify_all();
             }
             
- lock_guard<mutex> l1(thread_info_mutex);
             if(thread_info==local_thread_info)
             {
                 thread_info.reset();
@@ -296,17 +293,14 @@
 
     bool thread::joinable() const
     {
- return get_thread_info();
+ return (get_thread_info)();
     }
 
 
     void thread::detach()
     {
         detail::thread_data_ptr local_thread_info;
- {
- lock_guard<mutex> l1(thread_info_mutex);
- thread_info.swap(local_thread_info);
- }
+ thread_info.swap(local_thread_info);
         
         if(local_thread_info)
         {
@@ -381,8 +375,6 @@
     {
 #if defined(PTW32_VERSION) || defined(__hpux)
         return pthread_num_processors_np();
-#elif defined(_GNU_SOURCE)
- return get_nprocs();
 #elif defined(__APPLE__) || defined(__FreeBSD__)
         int count;
         size_t size=sizeof(count);
@@ -390,6 +382,8 @@
 #elif defined(BOOST_HAS_UNISTD_H) && defined(_SC_NPROCESSORS_ONLN)
         int const count=sysconf(_SC_NPROCESSORS_ONLN);
         return (count>0)?count:0;
+#elif defined(_GNU_SOURCE)
+ return get_nprocs();
 #else
         return 0;
 #endif
@@ -397,7 +391,7 @@
 
     thread::id thread::get_id() const
     {
- detail::thread_data_ptr const local_thread_info=get_thread_info();
+ detail::thread_data_ptr const local_thread_info=(get_thread_info)();
         if(local_thread_info)
         {
             return id(local_thread_info);
@@ -410,7 +404,7 @@
 
     void thread::interrupt()
     {
- detail::thread_data_ptr const local_thread_info=get_thread_info();
+ detail::thread_data_ptr const local_thread_info=(get_thread_info)();
         if(local_thread_info)
         {
             lock_guard<mutex> lk(local_thread_info->data_mutex);
@@ -424,7 +418,7 @@
 
     bool thread::interruption_requested() const
     {
- detail::thread_data_ptr const local_thread_info=get_thread_info();
+ detail::thread_data_ptr const local_thread_info=(get_thread_info)();
         if(local_thread_info)
         {
             lock_guard<mutex> lk(local_thread_info->data_mutex);
@@ -438,7 +432,7 @@
 
     thread::native_handle_type thread::native_handle()
     {
- detail::thread_data_ptr const local_thread_info=get_thread_info();
+ detail::thread_data_ptr const local_thread_info=(get_thread_info)();
         if(local_thread_info)
         {
             lock_guard<mutex> lk(local_thread_info->data_mutex);
@@ -582,11 +576,11 @@
         {
             if(tss_data_node* const current_node=find_tss_data(key))
             {
- if(cleanup_existing && current_node->func && current_node->value)
+ if(cleanup_existing && current_node->func && (current_node->value!=0))
                 {
                     (*current_node->func)(current_node->value);
                 }
- if(func || tss_data)
+ if(func || (tss_data!=0))
                 {
                     current_node->func=func;
                     current_node->value=tss_data;

Modified: branches/release/libs/thread/src/win32/thread.cpp
==============================================================================
--- branches/release/libs/thread/src/win32/thread.cpp (original)
+++ branches/release/libs/thread/src/win32/thread.cpp 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -244,17 +244,17 @@
     
     thread::id thread::get_id() const
     {
- return thread::id(get_thread_info());
+ return thread::id((get_thread_info)());
     }
 
     bool thread::joinable() const
     {
- return get_thread_info();
+ return (get_thread_info)();
     }
 
     void thread::join()
     {
- detail::thread_data_ptr local_thread_info=get_thread_info();
+ detail::thread_data_ptr local_thread_info=(get_thread_info)();
         if(local_thread_info)
         {
             this_thread::interruptible_wait(local_thread_info->thread_handle,detail::timeout::sentinel());
@@ -264,7 +264,7 @@
 
     bool thread::timed_join(boost::system_time const& wait_until)
     {
- detail::thread_data_ptr local_thread_info=get_thread_info();
+ detail::thread_data_ptr local_thread_info=(get_thread_info)();
         if(local_thread_info)
         {
             if(!this_thread::interruptible_wait(local_thread_info->thread_handle,get_milliseconds_until(wait_until)))
@@ -283,13 +283,12 @@
 
     void thread::release_handle()
     {
- lock_guard<mutex> l1(thread_info_mutex);
         thread_info=0;
     }
     
     void thread::interrupt()
     {
- detail::thread_data_ptr local_thread_info=get_thread_info();
+ detail::thread_data_ptr local_thread_info=(get_thread_info)();
         if(local_thread_info)
         {
             local_thread_info->interrupt();
@@ -298,26 +297,25 @@
     
     bool thread::interruption_requested() const
     {
- detail::thread_data_ptr local_thread_info=get_thread_info();
+ detail::thread_data_ptr local_thread_info=(get_thread_info)();
         return local_thread_info.get() && (detail::win32::WaitForSingleObject(local_thread_info->interruption_handle,0)==0);
     }
     
     unsigned thread::hardware_concurrency()
     {
- SYSTEM_INFO info={0};
+ SYSTEM_INFO info={{0}};
         GetSystemInfo(&info);
         return info.dwNumberOfProcessors;
     }
     
     thread::native_handle_type thread::native_handle()
     {
- detail::thread_data_ptr local_thread_info=get_thread_info();
+ detail::thread_data_ptr local_thread_info=(get_thread_info)();
         return local_thread_info?(detail::win32::handle)local_thread_info->thread_handle:detail::win32::invalid_handle_value;
     }
 
- detail::thread_data_ptr thread::get_thread_info() const
+ detail::thread_data_ptr thread::get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const
     {
- boost::mutex::scoped_lock l(thread_info_mutex);
         return thread_info;
     }
 
@@ -327,7 +325,7 @@
         {
             LARGE_INTEGER get_due_time(detail::timeout const& target_time)
             {
- LARGE_INTEGER due_time={0};
+ LARGE_INTEGER due_time={{0}};
                 if(target_time.relative)
                 {
                     unsigned long const elapsed_milliseconds=GetTickCount()-target_time.start;
@@ -356,7 +354,23 @@
                     else
                     {
                         long const hundred_nanoseconds_in_one_second=10000000;
- due_time.QuadPart+=target_time.abs_time.time_of_day().fractional_seconds()*(hundred_nanoseconds_in_one_second/target_time.abs_time.time_of_day().ticks_per_second());
+ posix_time::time_duration::tick_type const ticks_per_second=
+ target_time.abs_time.time_of_day().ticks_per_second();
+ if(ticks_per_second>hundred_nanoseconds_in_one_second)
+ {
+ posix_time::time_duration::tick_type const
+ ticks_per_hundred_nanoseconds=
+ ticks_per_second/hundred_nanoseconds_in_one_second;
+ due_time.QuadPart+=
+ target_time.abs_time.time_of_day().fractional_seconds()/
+ ticks_per_hundred_nanoseconds;
+ }
+ else
+ {
+ due_time.QuadPart+=
+ target_time.abs_time.time_of_day().fractional_seconds()*
+ (hundred_nanoseconds_in_one_second/ticks_per_second);
+ }
                     }
                 }
                 return due_time;
@@ -577,22 +591,22 @@
             }
         }
     }
-}
+ BOOST_THREAD_DECL void __cdecl on_process_enter()
+ {}
 
+ BOOST_THREAD_DECL void __cdecl on_thread_enter()
+ {}
 
-extern "C" BOOST_THREAD_DECL void on_process_enter()
-{}
+ BOOST_THREAD_DECL void __cdecl on_process_exit()
+ {
+ boost::cleanup_tls_key();
+ }
 
-extern "C" BOOST_THREAD_DECL void on_thread_enter()
-{}
+ BOOST_THREAD_DECL void __cdecl on_thread_exit()
+ {
+ boost::run_thread_exit_callbacks();
+ }
 
-extern "C" BOOST_THREAD_DECL void on_process_exit()
-{
- boost::cleanup_tls_key();
 }
 
-extern "C" BOOST_THREAD_DECL void on_thread_exit()
-{
- boost::run_thread_exit_callbacks();
-}
 

Modified: branches/release/libs/thread/src/win32/tss_dll.cpp
==============================================================================
--- branches/release/libs/thread/src/win32/tss_dll.cpp (original)
+++ branches/release/libs/thread/src/win32/tss_dll.cpp 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -24,27 +24,27 @@
         {
             case DLL_PROCESS_ATTACH:
             {
- on_process_enter();
- on_thread_enter();
+ boost::on_process_enter();
+ boost::on_thread_enter();
                 break;
             }
 
             case DLL_THREAD_ATTACH:
             {
- on_thread_enter();
+ boost::on_thread_enter();
                 break;
             }
 
             case DLL_THREAD_DETACH:
             {
- on_thread_exit();
+ boost::on_thread_exit();
                 break;
             }
 
             case DLL_PROCESS_DETACH:
             {
- on_thread_exit();
- on_process_exit();
+ boost::on_thread_exit();
+ boost::on_process_exit();
                 break;
             }
         }
@@ -52,7 +52,9 @@
         return TRUE;
     }
 
- extern "C" void tss_cleanup_implemented(void)
+namespace boost
+{
+ void tss_cleanup_implemented()
     {
         /*
         This function's sole purpose is to cause a link error in cases where
@@ -68,5 +70,7 @@
         longer needed and can be removed.
         */
     }
+}
+
 
 #endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL)

Modified: branches/release/libs/thread/src/win32/tss_pe.cpp
==============================================================================
--- branches/release/libs/thread/src/win32/tss_pe.cpp (original)
+++ branches/release/libs/thread/src/win32/tss_pe.cpp 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -19,7 +19,10 @@
 
 #include <cstdlib>
 
-extern "C" void tss_cleanup_implemented(void) {}
+namespace boost
+{
+ void tss_cleanup_implemented() {}
+}
 
 namespace {
     void NTAPI on_tls_callback(void* h, DWORD dwReason, PVOID pv)
@@ -28,33 +31,18 @@
         {
         case DLL_THREAD_DETACH:
         {
- on_thread_exit();
+ boost::on_thread_exit();
             break;
         }
         }
     }
-
- void on_after_ctors(void)
- {
- on_process_enter();
- }
-
- void on_before_dtors(void)
- {
- on_thread_exit();
- }
-
- void on_after_dtors(void)
- {
- on_process_exit();
- }
 }
 
 extern "C" {
 
- void (* after_ctors )(void) __attribute__((section(".ctors"))) = on_after_ctors;
- void (* before_dtors)(void) __attribute__((section(".dtors"))) = on_before_dtors;
- void (* after_dtors )(void) __attribute__((section(".dtors.zzz"))) = on_after_dtors;
+ void (* after_ctors )() __attribute__((section(".ctors"))) = boost::on_process_enter;
+ void (* before_dtors)() __attribute__((section(".dtors"))) = boost::on_thread_exit;
+ void (* after_dtors )() __attribute__((section(".dtors.zzz"))) = boost::on_process_exit;
 
     ULONG __tls_index__ = 0;
     char __tls_end__ __attribute__((section(".tls$zzz"))) = 0;
@@ -89,13 +77,13 @@
     //Definitions required by implementation
 
     #if (_MSC_VER < 1300) // 1300 == VC++ 7.0
- typedef void (__cdecl *_PVFV)(void);
+ typedef void (__cdecl *_PVFV)();
         #define INIRETSUCCESS
- #define PVAPI void
+ #define PVAPI void __cdecl
     #else
- typedef int (__cdecl *_PVFV)(void);
+ typedef int (__cdecl *_PVFV)();
         #define INIRETSUCCESS 0
- #define PVAPI int
+ #define PVAPI int __cdecl
     #endif
 
     typedef void (NTAPI* _TLSCB)(HINSTANCE, DWORD, PVOID);
@@ -112,9 +100,9 @@
     {
         //Forward declarations
 
- static PVAPI on_tls_prepare(void);
- static PVAPI on_process_init(void);
- static PVAPI on_process_term(void);
+ static PVAPI on_tls_prepare();
+ static PVAPI on_process_init();
+ static PVAPI on_process_term();
         static void NTAPI on_tls_callback(HINSTANCE, DWORD, PVOID);
 
         //The .CRT$Xxx information is taken from Codeguru:
@@ -169,7 +157,7 @@
 #pragma warning(disable:4189)
 #endif
 
- PVAPI on_tls_prepare(void)
+ PVAPI on_tls_prepare()
         {
             //The following line has an important side effect:
             //if the TLS directory is not already there, it will
@@ -210,7 +198,7 @@
 #pragma warning(pop)
 #endif
 
- PVAPI on_process_init(void)
+ PVAPI on_process_init()
         {
             //Schedule on_thread_exit() to be called for the main
             //thread before destructors of global objects have been
@@ -221,18 +209,18 @@
             //for destructors of global objects, so that
             //shouldn't be a problem.
 
- atexit(on_thread_exit);
+ atexit(boost::on_thread_exit);
 
             //Call Boost process entry callback here
 
- on_process_enter();
+ boost::on_process_enter();
 
             return INIRETSUCCESS;
         }
 
- PVAPI on_process_term(void)
+ PVAPI on_process_term()
         {
- on_process_exit();
+ boost::on_process_exit();
             return INIRETSUCCESS;
         }
 
@@ -241,7 +229,7 @@
             switch (dwReason)
             {
             case DLL_THREAD_DETACH:
- on_thread_exit();
+ boost::on_thread_exit();
                 break;
             }
         }
@@ -251,10 +239,10 @@
             switch (dwReason)
             {
             case DLL_THREAD_DETACH:
- on_thread_exit();
+ boost::on_thread_exit();
                 break;
             case DLL_PROCESS_DETACH:
- on_process_exit();
+ boost::on_process_exit();
                 break;
             }
             return true;
@@ -265,8 +253,9 @@
 {
     extern BOOL (WINAPI * const _pRawDllMain)(HANDLE, DWORD, LPVOID)=&dll_callback;
 }
-
- extern "C" void tss_cleanup_implemented(void)
+namespace boost
+{
+ void tss_cleanup_implemented()
     {
         /*
         This function's sole purpose is to cause a link error in cases where
@@ -282,6 +271,8 @@
         longer needed and can be removed.
         */
     }
+}
+
 #endif //defined(_MSC_VER) && !defined(UNDER_CE)
 
 #endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)

Modified: branches/release/libs/thread/test/test_futures.cpp
==============================================================================
--- branches/release/libs/thread/test/test_futures.cpp (original)
+++ branches/release/libs/thread/test/test_futures.cpp 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -18,7 +18,7 @@
     template<typename T>
     typename boost::remove_reference<T>::type&& cast_to_rval(T&& t)
     {
- return t;
+ return static_cast<typename boost::remove_reference<T>::type&&>(t);
     }
 #else
     template<typename T>
@@ -556,7 +556,7 @@
     }
 }
 
-void do_nothing_callback(boost::promise<int>& pi)
+void do_nothing_callback(boost::promise<int>& /*pi*/)
 {
     boost::lock_guard<boost::mutex> lk(callback_mutex);
     ++callback_called;

Modified: branches/release/libs/thread/test/test_generic_locks.cpp
==============================================================================
--- branches/release/libs/thread/test/test_generic_locks.cpp (original)
+++ branches/release/libs/thread/test/test_generic_locks.cpp 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -296,11 +296,81 @@
     }
 }
 
-void test_lock_ten_in_range()
+class dummy_iterator:
+ public std::iterator<std::forward_iterator_tag,
+ dummy_mutex>
 {
- unsigned const num_mutexes=10;
+private:
+ dummy_mutex* p;
+public:
+ explicit dummy_iterator(dummy_mutex* p_):
+ p(p_)
+ {}
+
+ bool operator==(dummy_iterator const& other) const
+ {
+ return p==other.p;
+ }
+
+ bool operator!=(dummy_iterator const& other) const
+ {
+ return p!=other.p;
+ }
+
+ bool operator<(dummy_iterator const& other) const
+ {
+ return p<other.p;
+ }
+
+ dummy_mutex& operator*() const
+ {
+ return *p;
+ }
+
+ dummy_mutex* operator->() const
+ {
+ return p;
+ }
+
+ dummy_iterator operator++(int)
+ {
+ dummy_iterator temp(*this);
+ ++p;
+ return temp;
+ }
+
+ dummy_iterator& operator++()
+ {
+ ++p;
+ return *this;
+ }
+
+};
+
+
+void test_lock_five_in_range_custom_iterator()
+{
+ unsigned const num_mutexes=5;
     dummy_mutex mutexes[num_mutexes];
 
+ boost::lock(dummy_iterator(mutexes),dummy_iterator(mutexes+num_mutexes));
+
+ for(unsigned i=0;i<num_mutexes;++i)
+ {
+ BOOST_CHECK(mutexes[i].is_locked);
+ }
+}
+
+class dummy_mutex2:
+ public dummy_mutex
+{};
+
+
+void test_lock_ten_in_range_inherited_mutex()
+{
+ unsigned const num_mutexes=10;
+ dummy_mutex2 mutexes[num_mutexes];
+
     boost::lock(mutexes,mutexes+num_mutexes);
     
     for(unsigned i=0;i<num_mutexes;++i)
@@ -510,7 +580,8 @@
     test->add(BOOST_TEST_CASE(&test_lock_five_other_thread_locks_in_order));
     test->add(BOOST_TEST_CASE(&test_lock_five_other_thread_locks_in_different_order));
     test->add(BOOST_TEST_CASE(&test_lock_five_in_range));
- test->add(BOOST_TEST_CASE(&test_lock_ten_in_range));
+ test->add(BOOST_TEST_CASE(&test_lock_five_in_range_custom_iterator));
+ test->add(BOOST_TEST_CASE(&test_lock_ten_in_range_inherited_mutex));
     test->add(BOOST_TEST_CASE(&test_lock_ten_other_thread_locks_in_different_order));
     test->add(BOOST_TEST_CASE(&test_try_lock_two_uncontended));
     test->add(BOOST_TEST_CASE(&test_try_lock_two_first_locked));

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 2010-07-09 15:13:09 EDT (Fri, 09 Jul 2010)
@@ -138,6 +138,14 @@
     CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,reader_count+1);
 }
 
+void test_can_lock_upgrade_to_unique_if_currently_locked_upgrade()
+{
+ boost::shared_mutex mtx;
+ boost::upgrade_lock<boost::shared_mutex> l(mtx);
+ boost::upgrade_to_unique_lock<boost::shared_mutex> ul(l);
+ BOOST_CHECK(ul.owns_lock());
+}
+
 void test_if_other_thread_has_write_lock_try_lock_shared_returns_false()
 {
 
@@ -282,6 +290,7 @@
 
     test->add(BOOST_TEST_CASE(&test_only_one_upgrade_lock_permitted));
     test->add(BOOST_TEST_CASE(&test_can_lock_upgrade_if_currently_locked_shared));
+ test->add(BOOST_TEST_CASE(&test_can_lock_upgrade_to_unique_if_currently_locked_upgrade));
     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));


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