diff --git a/doc/tss.qbk b/doc/tss.qbk index 6a9ffc44..150bc025 100644 --- a/doc/tss.qbk +++ b/doc/tss.qbk @@ -41,6 +41,11 @@ order. If a cleanup routine sets the value of associated with an instance of `bo cleaned up, that value is added to the cleanup list. Cleanup finishes when there are no outstanding instances of `boost::thread_specific_ptr` with values. +Note: on some platforms, cleanup of thread-specific data is not +performed for threads created with the platform's native API. On those +platforms such cleanup is only done for threads that are started with +`boost::thread` unless `boost::on_thread_exit()` is called manually +from that thread. [section:thread_specific_ptr Class `thread_specific_ptr`] diff --git a/include/boost/thread/pthread/condition_variable.hpp b/include/boost/thread/pthread/condition_variable.hpp index 9c5bee27..160c7072 100644 --- a/include/boost/thread/pthread/condition_variable.hpp +++ b/include/boost/thread/pthread/condition_variable.hpp @@ -47,27 +47,39 @@ namespace boost inline void condition_variable::wait(unique_lock& m) { - thread_cv_detail::lock_on_exit > 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); + int res=0; + { + thread_cv_detail::lock_on_exit > 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) + { + boost::throw_exception(condition_error()); + } } inline bool condition_variable::timed_wait(unique_lock& m,boost::system_time const& wait_until) { thread_cv_detail::lock_on_exit > 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,&internal_mutex,&timeout); + int cond_res; + { + detail::interruption_checker check_for_interruption(&internal_mutex,&cond); + guard.activate(m); + struct timespec const timeout=detail::get_timespec(wait_until); + cond_res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); + } this_thread::interruption_point(); if(cond_res==ETIMEDOUT) { return false; } - BOOST_ASSERT(!cond_res); + if(cond_res) + { + boost::throw_exception(condition_error()); + } return true; } @@ -121,8 +133,8 @@ namespace boost detail::interruption_checker check_for_interruption(&internal_mutex,&cond); guard.activate(m); res=pthread_cond_wait(&cond,&internal_mutex); - this_thread::interruption_point(); } + this_thread::interruption_point(); if(res) { boost::throw_exception(condition_error()); @@ -145,8 +157,8 @@ namespace boost detail::interruption_checker check_for_interruption(&internal_mutex,&cond); guard.activate(m); res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); - this_thread::interruption_point(); } + this_thread::interruption_point(); if(res==ETIMEDOUT) { return false; diff --git a/include/boost/thread/win32/thread_heap_alloc.hpp b/include/boost/thread/win32/thread_heap_alloc.hpp index c210a910..b70623aa 100644 --- a/include/boost/thread/win32/thread_heap_alloc.hpp +++ b/include/boost/thread/win32/thread_heap_alloc.hpp @@ -56,7 +56,7 @@ namespace boost { namespace detail { - inline /*BOOST_THREAD_DECL*/ void* allocate_raw_heap_memory(unsigned size) + inline BOOST_THREAD_DECL void* allocate_raw_heap_memory(unsigned size) { void* const heap_memory=detail::win32::HeapAlloc(detail::win32::GetProcessHeap(),0,size); if(!heap_memory) @@ -66,7 +66,7 @@ namespace boost return heap_memory; } - inline /*BOOST_THREAD_DECL*/ void free_raw_heap_memory(void* heap_memory) + inline BOOST_THREAD_DECL void free_raw_heap_memory(void* heap_memory) { BOOST_VERIFY(detail::win32::HeapFree(detail::win32::GetProcessHeap(),0,heap_memory)!=0); } diff --git a/src/win32/thread.cpp b/src/win32/thread.cpp index 05c7a6c9..72bf4190 100644 --- a/src/win32/thread.cpp +++ b/src/win32/thread.cpp @@ -32,7 +32,12 @@ namespace boost { tss_cleanup_implemented(); // if anyone uses TSS, we need the cleanup linked in current_thread_tls_key=TlsAlloc(); - BOOST_ASSERT(current_thread_tls_key!=TLS_OUT_OF_INDEXES); + #if defined(UNDER_CE) + // Windows CE does not define the TLS_OUT_OF_INDEXES constant. + BOOST_ASSERT(current_thread_tls_key!=0xFFFFFFFF); + #else + BOOST_ASSERT(current_thread_tls_key!=TLS_OUT_OF_INDEXES); + #endif } void cleanup_tls_key()