summaryrefslogtreecommitdiff
path: root/boost/thread/pthread/condition_variable.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/thread/pthread/condition_variable.hpp')
-rw-r--r--boost/thread/pthread/condition_variable.hpp141
1 files changed, 93 insertions, 48 deletions
diff --git a/boost/thread/pthread/condition_variable.hpp b/boost/thread/pthread/condition_variable.hpp
index b30d37f9b0..a603351591 100644
--- a/boost/thread/pthread/condition_variable.hpp
+++ b/boost/thread/pthread/condition_variable.hpp
@@ -68,17 +68,14 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
+ pthread_mutex_t* the_mutex = &internal_mutex;
guard.activate(m);
- do {
- res = pthread_cond_wait(&cond,&internal_mutex);
- } while (res == EINTR);
#else
- //boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
pthread_mutex_t* the_mutex = m.mutex()->native_handle();
+#endif
do {
res = pthread_cond_wait(&cond,the_mutex);
} while (res == EINTR);
-#endif
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
this_thread::interruption_point();
@@ -99,18 +96,17 @@ namespace boost
boost::throw_exception(condition_error(EPERM, "boost::condition_variable::do_wait_until() failed precondition mutex not owned"));
}
#endif
- thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
int cond_res;
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
+ pthread_mutex_t* the_mutex = &internal_mutex;
guard.activate(m);
- cond_res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
#else
- //boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
pthread_mutex_t* the_mutex = m.mutex()->native_handle();
- cond_res=pthread_cond_timedwait(&cond,the_mutex,&timeout);
#endif
+ cond_res=pthread_cond_timedwait(&cond,the_mutex,&timeout);
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
this_thread::interruption_point();
@@ -156,11 +152,11 @@ namespace boost
{
boost::throw_exception(thread_resource_error(res, "boost::condition_variable_any::condition_variable_any() failed in pthread_mutex_init"));
}
- int const res2=pthread_cond_init(&cond,NULL);
+ int const res2 = detail::monotonic_pthread_cond_init(cond);
if(res2)
{
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
- boost::throw_exception(thread_resource_error(res2, "boost::condition_variable_any::condition_variable_any() failed in pthread_cond_init"));
+ boost::throw_exception(thread_resource_error(res2, "boost::condition_variable_any::condition_variable_any() failed in detail::monotonic_pthread_cond_init"));
}
}
~condition_variable_any()
@@ -178,7 +174,7 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
#else
- boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
+ boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
#endif
guard.activate(m);
res=pthread_cond_wait(&cond,&internal_mutex);
@@ -240,6 +236,8 @@ namespace boost
return timed_wait(m,get_system_time()+wait_duration,pred);
}
#endif
+#ifndef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+
#ifdef BOOST_THREAD_USES_CHRONO
template <class lock_type,class Duration>
cv_status
@@ -268,22 +266,6 @@ namespace boost
return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
}
- template <class lock_type, class Clock, class Duration, class Predicate>
- bool
- wait_until(
- lock_type& lock,
- const chrono::time_point<Clock, Duration>& t,
- Predicate pred)
- {
- while (!pred())
- {
- if (wait_until(lock, t) == cv_status::timeout)
- return pred();
- }
- return true;
- }
-
-
template <class lock_type, class Rep, class Period>
cv_status
wait_for(
@@ -299,28 +281,64 @@ namespace boost
}
+ template <class lock_type>
+ cv_status wait_until(
+ lock_type& lk,
+ chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
+ {
+ using namespace chrono;
+ nanoseconds d = tp.time_since_epoch();
+ timespec ts = boost::detail::to_timespec(d);
+ if (do_wait_until(lk, ts)) return cv_status::no_timeout;
+ else return cv_status::timeout;
+ }
+#endif
+#else // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+#ifdef BOOST_THREAD_USES_CHRONO
- template <class lock_type, class Rep, class Period, class Predicate>
- bool
- wait_for(
- lock_type& lock,
- const chrono::duration<Rep, Period>& d,
- Predicate pred)
+ template <class lock_type, class Duration>
+ cv_status
+ wait_until(
+ lock_type& lock,
+ const chrono::time_point<chrono::steady_clock, Duration>& t)
{
- return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
+ using namespace chrono;
+ typedef time_point<steady_clock, nanoseconds> nano_sys_tmpt;
+ wait_until(lock,
+ nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
+ return steady_clock::now() < t ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
-// while (!pred())
-// {
-// if (wait_for(lock, d) == cv_status::timeout)
-// return pred();
-// }
-// return true;
+ template <class lock_type, class Clock, class Duration>
+ cv_status
+ wait_until(
+ lock_type& lock,
+ const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ steady_clock::time_point s_now = steady_clock::now();
+ typename Clock::time_point c_now = Clock::now();
+ wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
+ return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
}
- template <class lock_type>
- cv_status wait_until(
- lock_type& lk,
- chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
+ template <class lock_type, class Rep, class Period>
+ cv_status
+ wait_for(
+ lock_type& lock,
+ const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ steady_clock::time_point c_now = steady_clock::now();
+ wait_until(lock, c_now + ceil<nanoseconds>(d));
+ return steady_clock::now() - c_now < d ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ inline cv_status wait_until(
+ unique_lock<mutex>& lk,
+ chrono::time_point<chrono::steady_clock, chrono::nanoseconds> tp)
{
using namespace chrono;
nanoseconds d = tp.time_since_epoch();
@@ -328,6 +346,35 @@ namespace boost
if (do_wait_until(lk, ts)) return cv_status::no_timeout;
else return cv_status::timeout;
}
+
+#endif
+#endif // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class lock_type, class Clock, class Duration, class Predicate>
+ bool
+ wait_until(
+ lock_type& lock,
+ const chrono::time_point<Clock, Duration>& t,
+ Predicate pred)
+ {
+ while (!pred())
+ {
+ if (wait_until(lock, t) == cv_status::timeout)
+ return pred();
+ }
+ return true;
+ }
+
+ template <class lock_type, class Rep, class Period, class Predicate>
+ bool
+ wait_for(
+ lock_type& lock,
+ const chrono::duration<Rep, Period>& d,
+ Predicate pred)
+ {
+ return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
+ }
#endif
void notify_one() BOOST_NOEXCEPT
@@ -354,7 +401,7 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
#else
- boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
+ boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
#endif
guard.activate(m);
res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
@@ -372,8 +419,6 @@ namespace boost
}
return true;
}
-
-
};
}