From aad2b35ac9272698bcb1e7739ef31e31ce142729 Mon Sep 17 00:00:00 2001 From: "Vicente J. Botet Escriba" Date: Sun, 18 Mar 2012 17:26:30 +0000 Subject: [PATCH] Thread: Fix bug on time related functions that should base the _for functions on the until_ ones [SVN r77375] --- include/boost/thread/detail/thread.hpp | 17 ++-- .../boost/thread/win32/basic_timed_mutex.hpp | 90 ++++++++++--------- src/win32/thread.cpp | 17 ++-- 3 files changed, 71 insertions(+), 53 deletions(-) diff --git a/include/boost/thread/detail/thread.hpp b/include/boost/thread/detail/thread.hpp index 59f2e66e..2efb86c0 100644 --- a/include/boost/thread/detail/thread.hpp +++ b/include/boost/thread/detail/thread.hpp @@ -503,19 +503,24 @@ namespace boost template bool try_join_for(const chrono::duration& rel_time) { - return try_join_for(chrono::ceil(rel_time)); + return try_join_until(chrono::steady_clock::now() + rel_time); } template bool try_join_until(const chrono::time_point& t) { using namespace chrono; + system_clock::time_point s_now = system_clock::now(); typename Clock::time_point c_now = Clock::now(); - return try_join_for(chrono::ceil(t - c_now)); + return try_join_until(s_now + ceil(t - c_now)); } -#endif - private: -#ifdef BOOST_THREAD_USES_CHRONO - bool do_try_join_for(chrono::milliseconds const &rel_time_in_milliseconds); + template + bool try_join_until(const chrono::time_point& t) + { + using namespace chrono; + typedef time_point nano_sys_tmpt; + return try_join_until(nano_sys_tmpt(ceil(t.time_since_epoch()))); + } + bool try_join_until(const chrono::time_point& tp); #endif public: diff --git a/include/boost/thread/win32/basic_timed_mutex.hpp b/include/boost/thread/win32/basic_timed_mutex.hpp index 52f3e803..f9743c2b 100644 --- a/include/boost/thread/win32/basic_timed_mutex.hpp +++ b/include/boost/thread/win32/basic_timed_mutex.hpp @@ -145,34 +145,7 @@ namespace boost } return true; } - bool try_lock_for(chrono::milliseconds const& rel_time) - { - if(try_lock()) - { - return true; - } - long old_count=active_count; - mark_waiting_and_try_lock(old_count); - if(old_count&lock_flag_value) - { - bool lock_acquired=false; - void* const sem=get_event(); - - do - { - if(win32::WaitForSingleObject(sem,static_cast(rel_time.count()))!=0) - { - BOOST_INTERLOCKED_DECREMENT(&active_count); - return false; - } - clear_waiting_and_try_lock(old_count); - lock_acquired=!(old_count&lock_flag_value); - } - while(!lock_acquired); - } - return true; - } template bool timed_lock(Duration const& timeout) @@ -185,19 +158,56 @@ namespace boost return timed_lock(system_time(timeout)); } - template - bool try_lock_for(const chrono::duration& rel_time) - { - using namespace chrono; - return try_lock_for(ceil(rel_time)); - } - template - bool try_lock_until(const chrono::time_point& t) - { - using namespace chrono; - typename Clock::time_point c_now = Clock::now(); - return try_lock_for(ceil(t - c_now)); - } + template + bool try_lock_for(const chrono::duration& rel_time) + { + return try_lock_until(chrono::steady_clock::now() + rel_time); + } + template + bool try_lock_until(const chrono::time_point& t) + { + using namespace chrono; + system_clock::time_point s_now = system_clock::now(); + typename Clock::time_point c_now = Clock::now(); + return try_lock_until(s_now + ceil(t - c_now)); + } + template + bool try_lock_until(const chrono::time_point& t) + { + using namespace chrono; + typedef time_point sys_tmpt; + return try_lock_until(sys_tmpt(chrono::ceil(t.time_since_epoch()))); + } + bool try_lock_until(const chrono::time_point& tp) + { + if(try_lock()) + { + return true; + } + long old_count=active_count; + mark_waiting_and_try_lock(old_count); + + if(old_count&lock_flag_value) + { + bool lock_acquired=false; + void* const sem=get_event(); + + do + { + chrono::milliseconds rel_time= chrono::ceil(tp-chrono::system_clock::now()); + + if(win32::WaitForSingleObject(sem,static_cast(rel_time.count()))!=0) + { + BOOST_INTERLOCKED_DECREMENT(&active_count); + return false; + } + clear_waiting_and_try_lock(old_count); + lock_acquired=!(old_count&lock_flag_value); + } + while(!lock_acquired); + } + return true; + } void unlock() { diff --git a/src/win32/thread.cpp b/src/win32/thread.cpp index a02a9eaf..09ba7316 100644 --- a/src/win32/thread.cpp +++ b/src/win32/thread.cpp @@ -319,7 +319,9 @@ namespace boost } #ifdef BOOST_THREAD_USES_CHRONO - bool thread::do_try_join_for(chrono::milliseconds const &rel_time_in_milliseconds) { + + bool thread::try_join_until(const chrono::time_point& tp) + { if (this_thread::get_id() == get_id()) { boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself")); @@ -327,15 +329,16 @@ namespace boost detail::thread_data_ptr local_thread_info=(get_thread_info)(); if(local_thread_info) { - if(!this_thread::interruptible_wait(local_thread_info->thread_handle,rel_time_in_milliseconds.count())) - { - return false; - } - release_handle(); + chrono::milliseconds rel_time= chrono::ceil(tp-chrono::system_clock::now()); + if(!this_thread::interruptible_wait(local_thread_info->thread_handle,rel_time.count())) + { + return false; + } + release_handle(); } return true; - } + #endif void thread::detach()