$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r66259 - in branches/release: boost boost/thread boost/thread/pthread libs/thread libs/thread/src libs/thread/src/pthread libs/thread/src/win32
From: anthony_at_[hidden]
Date: 2010-10-29 19:27:09
Author: anthonyw
Date: 2010-10-29 19:27:00 EDT (Fri, 29 Oct 2010)
New Revision: 66259
URL: http://svn.boost.org/trac/boost/changeset/66259
Log:
Merged Boost.Thread 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/future.hpp                            |    20 +++++++---                              
   branches/release/boost/thread/pthread/condition_variable.hpp        |    72 ++++++++++++++++++++++++++++++----------
   branches/release/boost/thread/pthread/condition_variable_fwd.hpp    |    10 +++++                                   
   branches/release/boost/thread/pthread/pthread_mutex_scoped_lock.hpp |    14 ++++++-                                 
   branches/release/boost/thread/pthread/thread_data.hpp               |    26 +++++++++++--                           
   branches/release/boost/thread/thread_time.hpp                       |     5 ++                                      
   branches/release/libs/thread/src/pthread/thread.cpp                 |     1                                         
   branches/release/libs/thread/src/tss_null.cpp                       |     6 ++                                      
   branches/release/libs/thread/src/win32/tss_pe.cpp                   |     9 +++-                                    
   9 files changed, 128 insertions(+), 35 deletions(-)
Modified: branches/release/boost/thread/future.hpp
==============================================================================
--- branches/release/boost/thread/future.hpp	(original)
+++ branches/release/boost/thread/future.hpp	2010-10-29 19:27:00 EDT (Fri, 29 Oct 2010)
@@ -912,10 +912,10 @@
 
         void lazy_init()
         {
-            if(!future)
+            if(!atomic_load(&future))
             {
-                future_obtained=false;
-                future.reset(new detail::future_object<R>);
+                future_ptr blank;
+                atomic_compare_exchange(&future,&blank,future_ptr(new detail::future_object<R>));
             }
         }
         
@@ -945,12 +945,14 @@
             future_obtained(rhs.future_obtained)
         {
             future.swap(rhs.future);
+            rhs.future_obtained=false;
         }
         promise & operator=(promise&& rhs)
         {
             future.swap(rhs.future);
             future_obtained=rhs.future_obtained;
             rhs.future.reset();
+            rhs.future_obtained=false;
             return *this;
         }
 #else
@@ -958,12 +960,14 @@
             future(rhs->future),future_obtained(rhs->future_obtained)
         {
             rhs->future.reset();
+            rhs->future_obtained=false;
         }
         promise & operator=(boost::detail::thread_move_t<promise> rhs)
         {
             future=rhs->future;
             future_obtained=rhs->future_obtained;
             rhs->future.reset();
+            rhs->future_obtained=false;
             return *this;
         }
 
@@ -1047,10 +1051,10 @@
 
         void lazy_init()
         {
-            if(!future)
+            if(!atomic_load(&future))
             {
-                future_obtained=false;
-                future.reset(new detail::future_object<void>);
+                future_ptr blank;
+                atomic_compare_exchange(&future,&blank,future_ptr(new detail::future_object<void>));
             }
         }
     public:
@@ -1079,12 +1083,14 @@
             future_obtained(rhs.future_obtained)
         {
             future.swap(rhs.future);
+            rhs.future_obtained=false;
         }
         promise & operator=(promise&& rhs)
         {
             future.swap(rhs.future);
             future_obtained=rhs.future_obtained;
             rhs.future.reset();
+            rhs.future_obtained=false;
             return *this;
         }
 #else
@@ -1092,12 +1098,14 @@
             future(rhs->future),future_obtained(rhs->future_obtained)
         {
             rhs->future.reset();
+            rhs->future_obtained=false;
         }
         promise & operator=(boost::detail::thread_move_t<promise> rhs)
         {
             future=rhs->future;
             future_obtained=rhs->future_obtained;
             rhs->future.reset();
+            rhs->future_obtained=false;
             return *this;
         }
 
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-10-29 19:27:00 EDT (Fri, 29 Oct 2010)
@@ -14,17 +14,55 @@
 
 namespace boost
 {
+    namespace this_thread
+    {
+        void BOOST_THREAD_DECL interruption_point();
+    }
+    
+    namespace thread_cv_detail
+    {
+        template<typename MutexType>
+        struct lock_on_exit
+        {
+            MutexType* m;
+            
+            lock_on_exit():
+                m(0)
+            {}
+
+            void activate(MutexType& m_)
+            {
+                m_.unlock();
+                m=&m_;
+            }
+            ~lock_on_exit()
+            {
+                if(m)
+                {
+                    m->lock();
+                }
+           }
+        };
+    }
+    
     inline void condition_variable::wait(unique_lock<mutex>& m)
     {
-        detail::interruption_checker check_for_interruption(&cond);
-        BOOST_VERIFY(!pthread_cond_wait(&cond,m.mutex()->native_handle()));
+        thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
+        detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
+        guard.activate(m);
+        int const res=pthread_cond_wait(&cond,&internal_mutex);
+        BOOST_ASSERT(!res);
+        this_thread::interruption_point();
     }
 
     inline bool condition_variable::timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until)
     {
-        detail::interruption_checker check_for_interruption(&cond);
+        thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
+        detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
+        guard.activate(m);
         struct timespec const timeout=detail::get_timespec(wait_until);
-        int const cond_res=pthread_cond_timedwait(&cond,m.mutex()->native_handle(),&timeout);
+        int const cond_res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
+        this_thread::interruption_point();
         if(cond_res==ETIMEDOUT)
         {
             return false;
@@ -35,11 +73,13 @@
 
     inline void condition_variable::notify_one()
     {
+        boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
         BOOST_VERIFY(!pthread_cond_signal(&cond));
     }
         
     inline void condition_variable::notify_all()
     {
+        boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
         BOOST_VERIFY(!pthread_cond_broadcast(&cond));
     }
     
@@ -77,13 +117,11 @@
         {
             int res=0;
             {
-                detail::interruption_checker check_for_interruption(&cond);
-                {
-                    boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
-                    m.unlock();
-                    res=pthread_cond_wait(&cond,&internal_mutex);
-                }
-                m.lock();
+                thread_cv_detail::lock_on_exit<lock_type> guard;
+                detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
+                guard.activate(m);
+                res=pthread_cond_wait(&cond,&internal_mutex);
+                this_thread::interruption_point();
             }
             if(res)
             {
@@ -103,13 +141,11 @@
             struct timespec const timeout=detail::get_timespec(wait_until);
             int res=0;
             {
-                detail::interruption_checker check_for_interruption(&cond);
-                {
-                    boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
-                    m.unlock();
-                    res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
-                }
-                m.lock();
+                thread_cv_detail::lock_on_exit<lock_type> guard;
+                detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
+                guard.activate(m);
+                res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
+                this_thread::interruption_point();
             }
             if(res==ETIMEDOUT)
             {
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-10-29 19:27:00 EDT (Fri, 29 Oct 2010)
@@ -20,6 +20,7 @@
     class condition_variable
     {
     private:
+        pthread_mutex_t internal_mutex;
         pthread_cond_t cond;
         
         condition_variable(condition_variable&);
@@ -28,14 +29,21 @@
     public:
         condition_variable()
         {
-            int const res=pthread_cond_init(&cond,NULL);
+            int const res=pthread_mutex_init(&internal_mutex,NULL);
             if(res)
             {
                 boost::throw_exception(thread_resource_error());
             }
+            int const res2=pthread_cond_init(&cond,NULL);
+            if(res2)
+            {
+                BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
+                boost::throw_exception(thread_resource_error());
+            }
         }
         ~condition_variable()
         {
+            BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
             BOOST_VERIFY(!pthread_cond_destroy(&cond));
         }
 
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	2010-10-29 19:27:00 EDT (Fri, 29 Oct 2010)
@@ -18,15 +18,25 @@
         class pthread_mutex_scoped_lock
         {
             pthread_mutex_t* m;
+            bool locked;
         public:
             explicit pthread_mutex_scoped_lock(pthread_mutex_t* m_):
-                m(m_)
+                m(m_),locked(true)
             {
                 BOOST_VERIFY(!pthread_mutex_lock(m));
             }
-            ~pthread_mutex_scoped_lock()
+            void unlock()
             {
                 BOOST_VERIFY(!pthread_mutex_unlock(m));
+                locked=false;
+            }
+            
+            ~pthread_mutex_scoped_lock()
+            {
+                if(locked)
+                {
+                    unlock();
+                }
             }
             
         };
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	2010-10-29 19:27:00 EDT (Fri, 29 Oct 2010)
@@ -12,6 +12,7 @@
 #include <boost/thread/mutex.hpp>
 #include <boost/optional.hpp>
 #include <pthread.h>
+#include <boost/assert.hpp>
 #include "condition_variable_fwd.hpp"
 #include <map>
 
@@ -55,6 +56,7 @@
             std::map<void const*,boost::detail::tss_data_node> tss_data;
             bool interrupt_enabled;
             bool interrupt_requested;
+            pthread_mutex_t* cond_mutex;
             pthread_cond_t* current_cond;
 
             thread_data_base():
@@ -76,6 +78,8 @@
         class interruption_checker
         {
             thread_data_base* const thread_info;
+            pthread_mutex_t* m;
+            bool set;
 
             void check_for_interruption()
             {
@@ -88,23 +92,35 @@
             
             void operator=(interruption_checker&);
         public:
-            explicit interruption_checker(pthread_cond_t* cond):
-                thread_info(detail::get_current_thread_data())
+            explicit interruption_checker(pthread_mutex_t* cond_mutex,pthread_cond_t* cond):
+                thread_info(detail::get_current_thread_data()),m(cond_mutex),
+                set(thread_info && thread_info->interrupt_enabled)
             {
-                if(thread_info && thread_info->interrupt_enabled)
+                if(set)
                 {
                     lock_guard<mutex> guard(thread_info->data_mutex);
                     check_for_interruption();
+                    thread_info->cond_mutex=cond_mutex;
                     thread_info->current_cond=cond;
+                    BOOST_VERIFY(!pthread_mutex_lock(m));
+                }
+                else
+                {
+                    BOOST_VERIFY(!pthread_mutex_lock(m));
                 }
             }
             ~interruption_checker()
             {
-                if(thread_info && thread_info->interrupt_enabled)
+                if(set)
                 {
+                    BOOST_VERIFY(!pthread_mutex_unlock(m));
                     lock_guard<mutex> guard(thread_info->data_mutex);
+                    thread_info->cond_mutex=NULL;
                     thread_info->current_cond=NULL;
-                    check_for_interruption();
+                }
+                else
+                {
+                    BOOST_VERIFY(!pthread_mutex_unlock(m));
                 }
             }
         };
Modified: branches/release/boost/thread/thread_time.hpp
==============================================================================
--- branches/release/boost/thread/thread_time.hpp	(original)
+++ branches/release/boost/thread/thread_time.hpp	2010-10-29 19:27:00 EDT (Fri, 29 Oct 2010)
@@ -6,6 +6,7 @@
 //  accompanying file LICENSE_1_0.txt or copy at
 //  http://www.boost.org/LICENSE_1_0.txt)
 
+#include <boost/date_time/time_clock.hpp>
 #include <boost/date_time/microsec_time_clock.hpp>
 #include <boost/date_time/posix_time/posix_time_types.hpp>
 
@@ -17,7 +18,11 @@
     
     inline system_time get_system_time()
     {
+#if defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
         return boost::date_time::microsec_clock<system_time>::universal_time();
+#else // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
+        return boost::date_time::second_clock<system_time>::universal_time();
+#endif // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
     }
 
     namespace detail
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-10-29 19:27:00 EDT (Fri, 29 Oct 2010)
@@ -411,6 +411,7 @@
             local_thread_info->interrupt_requested=true;
             if(local_thread_info->current_cond)
             {
+                boost::pthread::pthread_mutex_scoped_lock internal_lock(local_thread_info->cond_mutex);
                 BOOST_VERIFY(!pthread_cond_broadcast(local_thread_info->current_cond));
             }
         }
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	2010-10-29 19:27:00 EDT (Fri, 29 Oct 2010)
@@ -8,13 +8,15 @@
 
 #if defined(BOOST_HAS_WINTHREADS) && (defined(BOOST_THREAD_BUILD_LIB) || defined(BOOST_THREAD_TEST) || defined(UNDER_CE)) && (!defined(_MSC_VER) || defined(UNDER_CE))
 
+namespace boost 
+{
     /*
     This file is a "null" implementation of tss cleanup; it's
     purpose is to to eliminate link errors in cases
     where it is known that tss cleanup is not needed.
     */
 
-    extern "C" void tss_cleanup_implemented(void)
+    void tss_cleanup_implemented(void)
     {
         /*
         This function's sole purpose is to cause a link error in cases where
@@ -30,5 +32,7 @@
         longer needed and can be removed.
         */
     }
+	
+}
 
 #endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB) && !defined(_MSC_VER)
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-10-29 19:27:00 EDT (Fri, 29 Oct 2010)
@@ -38,6 +38,12 @@
     }
 }
 
+#if (__MINGW32_MAJOR_VERSION >3) || ((__MINGW32_MAJOR_VERSION==3) && (__MINGW32_MINOR_VERSION>=18))
+extern "C"
+{
+    PIMAGE_TLS_CALLBACK __crt_xl_tls_callback__ __attribute__ ((section(".CRT$XLB"))) = on_tls_callback;
+}
+#else
 extern "C" {
 
     void (* after_ctors )() __attribute__((section(".ctors")))     = boost::on_process_enter;
@@ -50,10 +56,8 @@
 
 
     PIMAGE_TLS_CALLBACK __crt_xl_start__ __attribute__ ((section(".CRT$XLA"))) = 0;
-    PIMAGE_TLS_CALLBACK __crt_xl_tls_callback__ __attribute__ ((section(".CRT$XLB"))) = on_tls_callback;
     PIMAGE_TLS_CALLBACK __crt_xl_end__ __attribute__ ((section(".CRT$XLZ"))) = 0;
 }
-
 extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata$T"))) =
 {
         (DWORD) &__tls_start__,
@@ -63,6 +67,7 @@
         (DWORD) 0,
         (DWORD) 0
 };
+#endif
 
 
 #elif  defined(_MSC_VER) && !defined(UNDER_CE)