Boost logo

Boost-Commit :

From: anthony_at_[hidden]
Date: 2007-11-01 14:04:56


Author: anthonyw
Date: 2007-11-01 14:04:55 EDT (Thu, 01 Nov 2007)
New Revision: 40653
URL: http://svn.boost.org/trac/boost/changeset/40653

Log:
added timed_join to thread
Text files modified:
   trunk/boost/thread/pthread/thread.hpp | 7 +++++
   trunk/boost/thread/win32/thread.hpp | 7 +++++
   trunk/libs/thread/src/pthread/thread.cpp | 49 +++++++++++++++++++++++++++++++++++++
   trunk/libs/thread/src/win32/thread.cpp | 14 ++++++++++
   trunk/libs/thread/test/test_once.cpp | 4 +-
   trunk/libs/thread/test/test_shared_mutex.cpp | 10 +------
   trunk/libs/thread/test/test_thread.cpp | 52 +++++++++++++++++++++++++++++++++++++++
   7 files changed, 132 insertions(+), 11 deletions(-)

Modified: trunk/boost/thread/pthread/thread.hpp
==============================================================================
--- trunk/boost/thread/pthread/thread.hpp (original)
+++ trunk/boost/thread/pthread/thread.hpp 2007-11-01 14:04:55 EDT (Thu, 01 Nov 2007)
@@ -146,6 +146,13 @@
 
         bool joinable() const;
         void join();
+ bool timed_join(const system_time& wait_until);
+
+ template<typename TimeDuration>
+ inline bool timed_join(TimeDuration const& rel_time)
+ {
+ return timed_join(get_system_time()+rel_time);
+ }
         void detach();
 
         static unsigned hardware_concurrency();

Modified: trunk/boost/thread/win32/thread.hpp
==============================================================================
--- trunk/boost/thread/win32/thread.hpp (original)
+++ trunk/boost/thread/win32/thread.hpp 2007-11-01 14:04:55 EDT (Thu, 01 Nov 2007)
@@ -131,6 +131,13 @@
 
         bool joinable() const;
         void join();
+ bool timed_join(const system_time& wait_until);
+
+ template<typename TimeDuration>
+ inline bool timed_join(TimeDuration const& rel_time)
+ {
+ return timed_join(get_system_time()+rel_time);
+ }
         void detach();
 
         static unsigned hardware_concurrency();

Modified: trunk/libs/thread/src/pthread/thread.cpp
==============================================================================
--- trunk/libs/thread/src/pthread/thread.cpp (original)
+++ trunk/libs/thread/src/pthread/thread.cpp 2007-11-01 14:04:55 EDT (Thu, 01 Nov 2007)
@@ -187,6 +187,55 @@
         }
     }
 
+ bool thread::timed_join(system_time const& wait_until)
+ {
+ boost::shared_ptr<detail::thread_data_base> const local_thread_info=get_thread_info();
+ if(local_thread_info)
+ {
+ bool do_join=false;
+
+ {
+ unique_lock<mutex> lock(local_thread_info->data_mutex);
+ while(!local_thread_info->done)
+ {
+ if(!local_thread_info->done_condition.timed_wait(lock,wait_until))
+ {
+ return false;
+ }
+ }
+ do_join=!local_thread_info->join_started;
+
+ if(do_join)
+ {
+ local_thread_info->join_started=true;
+ }
+ else
+ {
+ while(!local_thread_info->joined)
+ {
+ local_thread_info->done_condition.wait(lock);
+ }
+ }
+ }
+ if(do_join)
+ {
+ void* result=0;
+ int const res=pthread_join(local_thread_info->thread_handle,&result);
+ BOOST_ASSERT(!res);
+ lock_guard<mutex> lock(local_thread_info->data_mutex);
+ local_thread_info->joined=true;
+ local_thread_info->done_condition.notify_all();
+ }
+
+ lock_guard<mutex> l1(thread_info_mutex);
+ if(thread_info==local_thread_info)
+ {
+ thread_info.reset();
+ }
+ }
+ return true;
+ }
+
     bool thread::joinable() const
     {
         return get_thread_info();

Modified: trunk/libs/thread/src/win32/thread.cpp
==============================================================================
--- trunk/libs/thread/src/win32/thread.cpp (original)
+++ trunk/libs/thread/src/win32/thread.cpp 2007-11-01 14:04:55 EDT (Thu, 01 Nov 2007)
@@ -251,6 +251,20 @@
             release_handle();
         }
     }
+
+ bool thread::timed_join(boost::system_time const& wait_until)
+ {
+ boost::intrusive_ptr<detail::thread_data_base> local_thread_info=get_thread_info();
+ if(local_thread_info)
+ {
+ if(!this_thread::cancellable_wait(local_thread_info->thread_handle,get_milliseconds_until(wait_until)))
+ {
+ return false;
+ }
+ release_handle();
+ }
+ return true;
+ }
     
     void thread::detach()
     {

Modified: trunk/libs/thread/test/test_once.cpp
==============================================================================
--- trunk/libs/thread/test/test_once.cpp (original)
+++ trunk/libs/thread/test/test_once.cpp 2007-11-01 14:04:55 EDT (Thu, 01 Nov 2007)
@@ -142,8 +142,8 @@
         group.create_thread(&call_once_with_exception);
     }
     group.join_all();
- BOOST_CHECK_EQUAL(throw_before_third_pass::pass_counter,3);
- BOOST_CHECK_EQUAL(exception_counter,2);
+ BOOST_CHECK_EQUAL(throw_before_third_pass::pass_counter,3u);
+ BOOST_CHECK_EQUAL(exception_counter,2u);
 }
 
 

Modified: trunk/libs/thread/test/test_shared_mutex.cpp
==============================================================================
--- trunk/libs/thread/test/test_shared_mutex.cpp (original)
+++ trunk/libs/thread/test/test_shared_mutex.cpp 2007-11-01 14:04:55 EDT (Thu, 01 Nov 2007)
@@ -427,15 +427,9 @@
     CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
 
     boost::system_time const start=boost::get_system_time();
- boost::system_time const timeout=start+boost::posix_time::milliseconds(100);
+ boost::system_time const timeout=start+boost::posix_time::milliseconds(2000);
     bool const timed_lock_succeeded=rw_mutex.timed_lock_shared(timeout);
- boost::system_time const wakeup=boost::get_system_time();
- BOOST_CHECK(timeout<=(wakeup+boost::posix_time::milliseconds(1)));
- if(timeout>wakeup)
- {
- std::cout<<"timeout="<<timeout<<", wakeup="<<wakeup<<std::endl;
- }
-
+ BOOST_CHECK(in_range(boost::get_xtime(timeout),1));
     BOOST_CHECK(!timed_lock_succeeded);
     if(timed_lock_succeeded)
     {

Modified: trunk/libs/thread/test/test_thread.cpp
==============================================================================
--- trunk/libs/thread/test/test_thread.cpp (original)
+++ trunk/libs/thread/test/test_thread.cpp 2007-11-01 14:04:55 EDT (Thu, 01 Nov 2007)
@@ -141,7 +141,7 @@
     
     boost::thread thrd(boost::ref(f));
     thrd.join();
- BOOST_CHECK_EQUAL(f.value, 999);
+ BOOST_CHECK_EQUAL(f.value, 999u);
 }
 
 void test_creation_through_reference_wrapper()
@@ -149,6 +149,55 @@
     timed_test(&do_test_creation_through_reference_wrapper, 1);
 }
 
+struct long_running_thread
+{
+ boost::condition_variable cond;
+ boost::mutex mut;
+ bool done;
+
+ long_running_thread():
+ done(false)
+ {}
+
+ void operator()()
+ {
+ boost::mutex::scoped_lock lk(mut);
+ while(!done)
+ {
+ cond.wait(lk);
+ }
+ }
+};
+
+void do_test_timed_join()
+{
+ long_running_thread f;
+ boost::thread thrd(boost::ref(f));
+ BOOST_CHECK(thrd.joinable());
+ boost::system_time xt=delay(3);
+ bool const joined=thrd.timed_join(xt);
+ BOOST_CHECK(in_range(boost::get_xtime(xt), 2));
+ BOOST_CHECK(!joined);
+ BOOST_CHECK(thrd.joinable());
+ {
+ boost::mutex::scoped_lock lk(f.mut);
+ f.done=true;
+ f.cond.notify_one();
+ }
+
+ xt=delay(3);
+ bool const joined2=thrd.timed_join(xt);
+ boost::system_time const now=boost::get_system_time();
+ BOOST_CHECK(xt>now);
+ BOOST_CHECK(joined2);
+ BOOST_CHECK(!thrd.joinable());
+}
+
+void test_timed_join()
+{
+ timed_test(&do_test_timed_join, 10);
+}
+
 
 boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
 {
@@ -161,6 +210,7 @@
     test->add(BOOST_TEST_CASE(test_thread_cancels_at_cancellation_point));
     test->add(BOOST_TEST_CASE(test_thread_no_cancel_if_cancels_disabled_at_cancellation_point));
     test->add(BOOST_TEST_CASE(test_creation_through_reference_wrapper));
+ test->add(BOOST_TEST_CASE(test_timed_join));
 
     return test;
 }


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