|
Boost-Commit : |
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)
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