diff options
Diffstat (limited to '3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp | 114 |
1 files changed, 81 insertions, 33 deletions
diff --git a/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp b/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp index aa71007..b1b76b0 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp @@ -4,11 +4,13 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // (C) Copyright 2007-10 Anthony Williams -// (C) Copyright 2011 Vicente J. Botet Escriba +// (C) Copyright 2011-2012 Vicente J. Botet Escriba #include <boost/thread/pthread/timespec.hpp> #include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS #include <boost/thread/pthread/thread_data.hpp> +#endif #include <boost/thread/pthread/condition_variable_fwd.hpp> #ifdef BOOST_THREAD_USES_CHRONO #include <boost/chrono/system_clocks.hpp> @@ -20,10 +22,12 @@ namespace boost { +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS namespace this_thread { void BOOST_THREAD_DECL interruption_point(); } +#endif namespace thread_cv_detail { @@ -53,57 +57,88 @@ namespace boost inline void condition_variable::wait(unique_lock<mutex>& m) { +#if defined BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED + if(! m.owns_lock()) + { + boost::throw_exception(condition_error(-1, "boost::condition_variable::wait() failed precondition mutex not owned")); + } +#endif int res=0; { +#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); 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(); + do { + res = pthread_cond_wait(&cond,the_mutex); + } while (res == EINTR); +#endif } +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS this_thread::interruption_point(); +#endif if(res) { - boost::throw_exception(condition_error(res, "boost:: condition_variable constructor failed in pthread_cond_wait")); + boost::throw_exception(condition_error(res, "boost::condition_variable::wait failed in pthread_cond_wait")); } } - inline bool condition_variable::do_timed_wait( + inline bool condition_variable::do_wait_until( unique_lock<mutex>& m, struct timespec const &timeout) { +#if defined BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED if (!m.owns_lock()) - boost::throw_exception(condition_error(EPERM, "condition_variable do_timed_wait: mutex not locked")); - + { + 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 detail::interruption_checker check_for_interruption(&internal_mutex,&cond); 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 } +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS this_thread::interruption_point(); +#endif if(cond_res==ETIMEDOUT) { return false; } if(cond_res) { - boost::throw_exception(condition_error(cond_res, "condition_variable failed in pthread_cond_timedwait")); + boost::throw_exception(condition_error(cond_res, "boost::condition_variable::do_wait_until failed in pthread_cond_timedwait")); } return true; } inline void condition_variable::notify_one() BOOST_NOEXCEPT { +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); +#endif BOOST_VERIFY(!pthread_cond_signal(&cond)); } inline void condition_variable::notify_all() BOOST_NOEXCEPT { +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); +#endif BOOST_VERIFY(!pthread_cond_broadcast(&cond)); } @@ -119,13 +154,13 @@ namespace boost int const res=pthread_mutex_init(&internal_mutex,NULL); if(res) { - boost::throw_exception(thread_resource_error(res, "condition_variable_any failed in pthread_mutex_init")); + 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); if(res2) { BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex)); - boost::throw_exception(thread_resource_error(res, "condition_variable_any failed in pthread_cond_init")); + boost::throw_exception(thread_resource_error(res, "boost::condition_variable_any::condition_variable_any() failed in pthread_cond_init")); } } ~condition_variable_any() @@ -140,14 +175,20 @@ namespace boost int res=0; { thread_cv_detail::lock_on_exit<lock_type> guard; +#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); +#endif guard.activate(m); res=pthread_cond_wait(&cond,&internal_mutex); } +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS this_thread::interruption_point(); +#endif if(res) { - boost::throw_exception(condition_error(res, "condition_variable_any failed in pthread_cond_wait")); + boost::throw_exception(condition_error(res, "boost::condition_variable_any::wait() failed in pthread_cond_wait")); } } @@ -157,16 +198,17 @@ namespace boost while(!pred()) wait(m); } +#if defined BOOST_THREAD_USES_DATETIME template<typename lock_type> - bool timed_wait(lock_type& m,boost::system_time const& wait_until) + bool timed_wait(lock_type& m,boost::system_time const& abs_time) { - struct timespec const timeout=detail::get_timespec(wait_until); - return do_timed_wait(m, timeout); + struct timespec const timeout=detail::to_timespec(abs_time); + return do_wait_until(m, timeout); } template<typename lock_type> - bool timed_wait(lock_type& m,xtime const& wait_until) + bool timed_wait(lock_type& m,xtime const& abs_time) { - return timed_wait(m,system_time(wait_until)); + return timed_wait(m,system_time(abs_time)); } template<typename lock_type,typename duration_type> @@ -176,20 +218,20 @@ namespace boost } template<typename lock_type,typename predicate_type> - bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred) + bool timed_wait(lock_type& m,boost::system_time const& abs_time, predicate_type pred) { while (!pred()) { - if(!timed_wait(m, wait_until)) + if(!timed_wait(m, abs_time)) return pred(); } return true; } template<typename lock_type,typename predicate_type> - bool timed_wait(lock_type& m,xtime const& wait_until,predicate_type pred) + bool timed_wait(lock_type& m,xtime const& abs_time, predicate_type pred) { - return timed_wait(m,system_time(wait_until),pred); + return timed_wait(m,system_time(abs_time),pred); } template<typename lock_type,typename duration_type,typename predicate_type> @@ -197,7 +239,7 @@ namespace boost { return timed_wait(m,get_system_time()+wait_duration,pred); } - +#endif #ifdef BOOST_THREAD_USES_CHRONO template <class lock_type,class Duration> cv_status @@ -265,26 +307,26 @@ namespace boost const chrono::duration<Rep, Period>& d, Predicate pred) { - while (!pred()) - { - if (wait_for(lock, d) == cv_status::timeout) - return pred(); - } - return true; + return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred)); + +// while (!pred()) +// { +// if (wait_for(lock, d) == cv_status::timeout) +// return pred(); +// } +// return true; } template <class lock_type> - inline void wait_until( + 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; - seconds s = duration_cast<seconds>(d); - ts.tv_sec = static_cast<long>(s.count()); - ts.tv_nsec = static_cast<long>((d - s).count()); - do_timed_wait(lk, ts); + timespec ts = boost::detail::to_timespec(d); + if (do_wait_until(lk, ts)) return cv_status::no_timeout; + else return cv_status::timeout; } #endif @@ -302,25 +344,31 @@ namespace boost private: // used by boost::thread::try_join_until template <class lock_type> - inline bool do_timed_wait( + inline bool do_wait_until( lock_type& m, struct timespec const &timeout) { int res=0; { thread_cv_detail::lock_on_exit<lock_type> guard; +#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); +#endif guard.activate(m); res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); } +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS this_thread::interruption_point(); +#endif if(res==ETIMEDOUT) { return false; } if(res) { - boost::throw_exception(condition_error(res, "condition_variable_any failed in pthread_cond_timedwait")); + boost::throw_exception(condition_error(res, "boost::condition_variable_any::do_wait_until() failed in pthread_cond_timedwait")); } return true; } |