1 #ifndef BOOST_THREAD_CONDITION_VARIABLE_PTHREAD_HPP 2 #define BOOST_THREAD_CONDITION_VARIABLE_PTHREAD_HPP 13 #include <boost/thread/pthread/timespec.hpp> 14 #include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> 15 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 16 #include <boost/thread/pthread/thread_data.hpp> 19 #ifdef BOOST_THREAD_USES_CHRONO 20 #include <boost/chrono/system_clocks.hpp> 21 #include <boost/chrono/ceil.hpp> 23 #include <boost/thread/detail/delete.hpp> 25 #include <boost/config/abi_prefix.hpp> 29 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 32 void BOOST_THREAD_DECL interruption_point();
36 namespace thread_cv_detail
38 template<
typename MutexType>
64 #if defined BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED 67 boost::throw_exception(condition_error(-1,
"boost::condition_variable::wait() failed precondition mutex not owned"));
72 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 74 detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
75 pthread_mutex_t* the_mutex = &internal_mutex;
78 pthread_mutex_t* the_mutex = m.mutex()->native_handle();
80 res = pthread_cond_wait(&cond,the_mutex);
82 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 83 this_thread::interruption_point();
85 if(res && res != EINTR)
87 boost::throw_exception(condition_error(res,
"boost::condition_variable::wait failed in pthread_cond_wait"));
92 unique_lock<mutex>& m,
93 struct timespec
const &timeout)
95 #if defined BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED 98 boost::throw_exception(condition_error(EPERM,
"boost::condition_variable::do_wait_until() failed precondition mutex not owned"));
103 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 105 detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
106 pthread_mutex_t* the_mutex = &internal_mutex;
109 pthread_mutex_t* the_mutex = m.mutex()->native_handle();
111 cond_res=pthread_cond_timedwait(&cond,the_mutex,&timeout);
113 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 114 this_thread::interruption_point();
116 if(cond_res==ETIMEDOUT)
122 boost::throw_exception(condition_error(cond_res,
"boost::condition_variable::do_wait_until failed in pthread_cond_timedwait"));
129 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 130 boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
132 BOOST_VERIFY(!pthread_cond_signal(&cond));
137 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 138 boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
140 BOOST_VERIFY(!pthread_cond_broadcast(&cond));
152 int const res=pthread_mutex_init(&internal_mutex,NULL);
155 boost::throw_exception(thread_resource_error(res,
"boost::condition_variable_any::condition_variable_any() failed in pthread_mutex_init"));
160 BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
161 boost::throw_exception(thread_resource_error(res2,
"boost::condition_variable_any::condition_variable_any() failed in detail::monotonic_pthread_cond_init"));
166 BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
167 BOOST_VERIFY(!pthread_cond_destroy(&cond));
170 template<
typename lock_type>
176 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 177 detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
179 boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
182 res=pthread_cond_wait(&cond,&internal_mutex);
184 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 185 this_thread::interruption_point();
189 boost::throw_exception(condition_error(res,
"boost::condition_variable_any::wait() failed in pthread_cond_wait"));
193 template<
typename lock_type,
typename predicate_type>
194 void wait(lock_type& m,predicate_type pred)
196 while(!pred()) wait(m);
199 #if defined BOOST_THREAD_USES_DATETIME 200 template<
typename lock_type>
201 bool timed_wait(lock_type& m,boost::system_time
const& abs_time)
203 struct timespec const timeout=detail::to_timespec(abs_time);
204 return do_wait_until(m, timeout);
206 template<
typename lock_type>
207 bool timed_wait(lock_type& m,xtime
const& abs_time)
209 return timed_wait(m,system_time(abs_time));
212 template<
typename lock_type,
typename duration_type>
213 bool timed_wait(lock_type& m,duration_type
const& wait_duration)
215 return timed_wait(m,get_system_time()+wait_duration);
218 template<
typename lock_type,
typename predicate_type>
219 bool timed_wait(lock_type& m,boost::system_time
const& abs_time, predicate_type pred)
223 if(!timed_wait(m, abs_time))
229 template<
typename lock_type,
typename predicate_type>
230 bool timed_wait(lock_type& m,xtime
const& abs_time, predicate_type pred)
232 return timed_wait(m,system_time(abs_time),pred);
235 template<
typename lock_type,
typename duration_type,
typename predicate_type>
236 bool timed_wait(lock_type& m,duration_type
const& wait_duration,predicate_type pred)
238 return timed_wait(m,get_system_time()+wait_duration,pred);
241 #ifndef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC 243 #ifdef BOOST_THREAD_USES_CHRONO 244 template <
class lock_type,
class Duration>
248 const chrono::time_point<chrono::system_clock, Duration>& t)
250 using namespace chrono;
251 typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
253 nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
254 return system_clock::now() < t ? cv_status::no_timeout :
258 template <
class lock_type,
class Clock,
class Duration>
262 const chrono::time_point<Clock, Duration>& t)
264 using namespace chrono;
265 system_clock::time_point s_now = system_clock::now();
266 typename Clock::time_point c_now = Clock::now();
267 wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
268 return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
271 template <
class lock_type,
class Rep,
class Period>
275 const chrono::duration<Rep, Period>&
d)
277 using namespace chrono;
278 system_clock::time_point s_now = system_clock::now();
279 steady_clock::time_point c_now = steady_clock::now();
280 wait_until(lock, s_now + ceil<nanoseconds>(d));
281 return steady_clock::now() - c_now < d ? cv_status::no_timeout :
286 template <
class lock_type>
287 cv_status wait_until(
289 chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
291 using namespace chrono;
292 nanoseconds d = tp.time_since_epoch();
293 timespec ts = boost::detail::to_timespec(d);
294 if (do_wait_until(lk, ts))
return cv_status::no_timeout;
295 else return cv_status::timeout;
298 #else // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC 299 #ifdef BOOST_THREAD_USES_CHRONO 301 template <
class lock_type,
class Duration>
305 const chrono::time_point<chrono::steady_clock, Duration>& t)
307 using namespace chrono;
308 typedef time_point<steady_clock, nanoseconds> nano_sys_tmpt;
310 nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
311 return steady_clock::now() < t ? cv_status::no_timeout :
315 template <
class lock_type,
class Clock,
class Duration>
319 const chrono::time_point<Clock, Duration>& t)
321 using namespace chrono;
322 steady_clock::time_point s_now = steady_clock::now();
323 typename Clock::time_point c_now = Clock::now();
324 wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
325 return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
328 template <
class lock_type,
class Rep,
class Period>
332 const chrono::duration<Rep, Period>& d)
334 using namespace chrono;
335 steady_clock::time_point c_now = steady_clock::now();
336 wait_until(lock, c_now + ceil<nanoseconds>(d));
337 return steady_clock::now() - c_now < d ? cv_status::no_timeout :
341 template <
class lock_type>
342 inline cv_status wait_until(
344 chrono::time_point<chrono::steady_clock, chrono::nanoseconds> tp)
346 using namespace chrono;
347 nanoseconds d = tp.time_since_epoch();
348 timespec ts = boost::detail::to_timespec(d);
349 if (do_wait_until(lock, ts))
return cv_status::no_timeout;
350 else return cv_status::timeout;
354 #endif // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC 356 #ifdef BOOST_THREAD_USES_CHRONO 357 template <
class lock_type,
class Clock,
class Duration,
class Predicate>
361 const chrono::time_point<Clock, Duration>& t,
366 if (wait_until(lock, t) == cv_status::timeout)
372 template <
class lock_type,
class Rep,
class Period,
class Predicate>
376 const chrono::duration<Rep, Period>& d,
379 return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
385 boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
386 BOOST_VERIFY(!pthread_cond_signal(&cond));
391 boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
392 BOOST_VERIFY(!pthread_cond_broadcast(&cond));
396 template <
class lock_type>
399 struct timespec
const &timeout)
404 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 405 detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
407 boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
410 res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
412 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS 413 this_thread::interruption_point();
421 boost::throw_exception(condition_error(res,
"boost::condition_variable_any::do_wait_until() failed in pthread_cond_timedwait"));
429 #include <boost/config/abi_suffix.hpp>
void notify_all() BOOST_NOEXCEPT
~condition_variable_any()
bool do_wait_until(unique_lock< mutex > &lock, struct timespec const &timeout)
void wait(unique_lock< mutex > &m)
void notify_one() BOOST_NOEXCEPT
void notify_all() BOOST_NOEXCEPT
void wait(lock_type &m, predicate_type pred)
int monotonic_pthread_cond_init(pthread_cond_t &cond)
bool do_wait_until(lock_type &m, struct timespec const &timeout)
void activate(MutexType &m_)
pthread_mutex_t internal_mutex
void notify_one() BOOST_NOEXCEPT