|
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