boost_161_pthread_condition_variable_fwd.h
Go to the documentation of this file.
1 #ifndef BOOST_THREAD_PTHREAD_CONDITION_VARIABLE_FWD_HPP
2 #define BOOST_THREAD_PTHREAD_CONDITION_VARIABLE_FWD_HPP
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 // (C) Copyright 2007-8 Anthony Williams
7 // (C) Copyright 2011-2012 Vicente J. Botet Escriba
8 
9 // define to check if this backported version was included
10 #define USING_BACKPORTED_BOOST_CONDITION_VARIABLE 1
11 
12 #include <boost/assert.hpp>
13 #include <boost/throw_exception.hpp>
14 #include <pthread.h>
15 #include <boost/thread/cv_status.hpp>
16 #include <boost/thread/mutex.hpp>
17 #include <boost/thread/lock_types.hpp>
18 #include <boost/thread/thread_time.hpp>
19 #include <boost/thread/pthread/timespec.hpp>
20 #if defined BOOST_THREAD_USES_DATETIME
21 #include <boost/thread/xtime.hpp>
22 #endif
23 
24 #ifdef BOOST_THREAD_USES_CHRONO
25 #include <boost/chrono/system_clocks.hpp>
26 #include <boost/chrono/ceil.hpp>
27 #endif
28 #include <boost/thread/detail/delete.hpp>
29 #include <boost/date_time/posix_time/posix_time_duration.hpp>
30 
31 #include <boost/config/abi_prefix.hpp>
32 
33 namespace boost
34 {
35  namespace detail {
36  inline int monotonic_pthread_cond_init(pthread_cond_t& cond) {
37 
38 #ifdef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
39  pthread_condattr_t attr;
40  int res = pthread_condattr_init(&attr);
41  if (res)
42  {
43  return res;
44  }
45  pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
46  res=pthread_cond_init(&cond,&attr);
47  pthread_condattr_destroy(&attr);
48  return res;
49 #else
50  return pthread_cond_init(&cond,NULL);
51 #endif
52 
53  }
54  }
55 
57  {
58  private:
59 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
60  pthread_mutex_t internal_mutex;
61 #endif
62  pthread_cond_t cond;
63 
64  public:
65  //private: // used by boost::thread::try_join_until
66 
67  inline bool do_wait_until(
68  unique_lock<mutex>& lock,
69  struct timespec const &timeout);
70 
72  unique_lock<mutex>& lock,
73  struct timespec const &timeout)
74  {
75 #if ! defined BOOST_THREAD_USEFIXES_TIMESPEC
76  return do_wait_until(lock, boost::detail::timespec_plus(timeout, boost::detail::timespec_now()));
77 #elif ! defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
78  //using namespace chrono;
79  //nanoseconds ns = chrono::system_clock::now().time_since_epoch();
80 
81  struct timespec ts = boost::detail::timespec_now_realtime();
82  //ts.tv_sec = static_cast<long>(chrono::duration_cast<chrono::seconds>(ns).count());
83  //ts.tv_nsec = static_cast<long>((ns - chrono::duration_cast<chrono::seconds>(ns)).count());
84  return do_wait_until(lock, boost::detail::timespec_plus(timeout, ts));
85 #else
86  // old behavior was fine for monotonic
87  return do_wait_until(lock, boost::detail::timespec_plus(timeout, boost::detail::timespec_now_realtime()));
88 #endif
89  }
90 
91  public:
92  BOOST_THREAD_NO_COPYABLE(condition_variable)
94  {
95  int res;
96 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
97  res=pthread_mutex_init(&internal_mutex,NULL);
98  if(res)
99  {
100  boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in pthread_mutex_init"));
101  }
102 #endif
104  if (res)
105  {
106 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
107  BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
108 #endif
109  boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in detail::monotonic_pthread_cond_init"));
110  }
111  }
113  {
114  int ret;
115 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
116  do {
117  ret = pthread_mutex_destroy(&internal_mutex);
118  } while (ret == EINTR);
119  BOOST_ASSERT(!ret);
120 #endif
121  do {
122  ret = pthread_cond_destroy(&cond);
123  } while (ret == EINTR);
124  BOOST_ASSERT(!ret);
125  }
126 
127  void wait(unique_lock<mutex>& m);
128 
129  template<typename predicate_type>
130  void wait(unique_lock<mutex>& m,predicate_type pred)
131  {
132  while(!pred()) wait(m);
133  }
134 
135 #if defined BOOST_THREAD_USES_DATETIME
136  inline bool timed_wait(
137  unique_lock<mutex>& m,
138  boost::system_time const& abs_time)
139  {
140 #if defined BOOST_THREAD_WAIT_BUG
141  struct timespec const timeout=detail::to_timespec(abs_time + BOOST_THREAD_WAIT_BUG);
142  return do_wait_until(m, timeout);
143 #else
144  struct timespec const timeout=detail::to_timespec(abs_time);
145  return do_wait_until(m, timeout);
146 #endif
147  }
148  bool timed_wait(
149  unique_lock<mutex>& m,
150  xtime const& abs_time)
151  {
152  return timed_wait(m,system_time(abs_time));
153  }
154 
155  template<typename duration_type>
156  bool timed_wait(
157  unique_lock<mutex>& m,
158  duration_type const& wait_duration)
159  {
160  if (wait_duration.is_pos_infinity())
161  {
162  wait(m); // or do_wait(m,detail::timeout::sentinel());
163  return true;
164  }
165  if (wait_duration.is_special())
166  {
167  return true;
168  }
169  return timed_wait(m,get_system_time()+wait_duration);
170  }
171 
172  template<typename predicate_type>
173  bool timed_wait(
174  unique_lock<mutex>& m,
175  boost::system_time const& abs_time,predicate_type pred)
176  {
177  while (!pred())
178  {
179  if(!timed_wait(m, abs_time))
180  return pred();
181  }
182  return true;
183  }
184 
185  template<typename predicate_type>
186  bool timed_wait(
187  unique_lock<mutex>& m,
188  xtime const& abs_time,predicate_type pred)
189  {
190  return timed_wait(m,system_time(abs_time),pred);
191  }
192 
193  template<typename duration_type,typename predicate_type>
194  bool timed_wait(
195  unique_lock<mutex>& m,
196  duration_type const& wait_duration,predicate_type pred)
197  {
198  if (wait_duration.is_pos_infinity())
199  {
200  while (!pred())
201  {
202  wait(m); // or do_wait(m,detail::timeout::sentinel());
203  }
204  return true;
205  }
206  if (wait_duration.is_special())
207  {
208  return pred();
209  }
210  return timed_wait(m,get_system_time()+wait_duration,pred);
211  }
212 #endif
213 
214 #ifndef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
215 
216 #ifdef BOOST_THREAD_USES_CHRONO
217 
218  template <class Duration>
219  cv_status
220  wait_until(
221  unique_lock<mutex>& lock,
222  const chrono::time_point<chrono::system_clock, Duration>& t)
223  {
224  using namespace chrono;
225  typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
226  wait_until(lock,
227  nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
228  return system_clock::now() < t ? cv_status::no_timeout :
229  cv_status::timeout;
230  }
231 
232  template <class Clock, class Duration>
233  cv_status
234  wait_until(
235  unique_lock<mutex>& lock,
236  const chrono::time_point<Clock, Duration>& t)
237  {
238  using namespace chrono;
239  system_clock::time_point s_now = system_clock::now();
240  typename Clock::time_point c_now = Clock::now();
241  wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
242  return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
243  }
244 
245 
246 
247  template <class Rep, class Period>
248  cv_status
249  wait_for(
250  unique_lock<mutex>& lock,
251  const chrono::duration<Rep, Period>& d)
252  {
253  using namespace chrono;
254  system_clock::time_point s_now = system_clock::now();
255  steady_clock::time_point c_now = steady_clock::now();
256  wait_until(lock, s_now + ceil<nanoseconds>(d));
257  return steady_clock::now() - c_now < d ? cv_status::no_timeout :
258  cv_status::timeout;
259 
260  }
261 
262  inline cv_status wait_until(
263  unique_lock<mutex>& lk,
264  chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
265  {
266  using namespace chrono;
267  nanoseconds d = tp.time_since_epoch();
268  timespec ts = boost::detail::to_timespec(d);
269  if (do_wait_until(lk, ts)) return cv_status::no_timeout;
270  else return cv_status::timeout;
271  }
272 #endif
273 
274 #else // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
275 #ifdef BOOST_THREAD_USES_CHRONO
276 
277  template <class Duration>
278  cv_status
279  wait_until(
280  unique_lock<mutex>& lock,
281  const chrono::time_point<chrono::steady_clock, Duration>& t)
282  {
283  using namespace chrono;
284  typedef time_point<steady_clock, nanoseconds> nano_sys_tmpt;
285  wait_until(lock,
286  nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
287  return steady_clock::now() < t ? cv_status::no_timeout :
288  cv_status::timeout;
289  }
290 
291  template <class Clock, class Duration>
292  cv_status
293  wait_until(
294  unique_lock<mutex>& lock,
295  const chrono::time_point<Clock, Duration>& t)
296  {
297  using namespace chrono;
298  steady_clock::time_point s_now = steady_clock::now();
299  typename Clock::time_point c_now = Clock::now();
300  wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
301  return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
302  }
303 
304  template <class Rep, class Period>
305  cv_status
306  wait_for(
307  unique_lock<mutex>& lock,
308  const chrono::duration<Rep, Period>& d)
309  {
310  using namespace chrono;
311  steady_clock::time_point c_now = steady_clock::now();
312  wait_until(lock, c_now + ceil<nanoseconds>(d));
313  return steady_clock::now() - c_now < d ? cv_status::no_timeout :
314  cv_status::timeout;
315  }
316 
317  inline cv_status wait_until(
318  unique_lock<mutex>& lk,
319  chrono::time_point<chrono::steady_clock, chrono::nanoseconds> tp)
320  {
321  using namespace chrono;
322  nanoseconds d = tp.time_since_epoch();
323  timespec ts = boost::detail::to_timespec(d);
324  if (do_wait_until(lk, ts)) return cv_status::no_timeout;
325  else return cv_status::timeout;
326  }
327 #endif
328 
329 #endif // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
330 
331 #ifdef BOOST_THREAD_USES_CHRONO
332  template <class Clock, class Duration, class Predicate>
333  bool
334  wait_until(
335  unique_lock<mutex>& lock,
336  const chrono::time_point<Clock, Duration>& t,
337  Predicate pred)
338  {
339  while (!pred())
340  {
341  if (wait_until(lock, t) == cv_status::timeout)
342  return pred();
343  }
344  return true;
345  }
346 
347  template <class Rep, class Period, class Predicate>
348  bool
349  wait_for(
350  unique_lock<mutex>& lock,
351  const chrono::duration<Rep, Period>& d,
352  Predicate pred)
353  {
354  return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
355  }
356 #endif
357 
358 #define BOOST_THREAD_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE
359  typedef pthread_cond_t* native_handle_type;
360  native_handle_type native_handle()
361  {
362  return &cond;
363  }
364 
365  void notify_one() BOOST_NOEXCEPT;
366  void notify_all() BOOST_NOEXCEPT;
367 
368 
369  };
370 
371  BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
372 
373 }
374 
375 
376 #include <boost/config/abi_suffix.hpp>
377 
378 #endif
d
BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable &cond, unique_lock< mutex > lk)
bool do_wait_for(unique_lock< mutex > &lock, struct timespec const &timeout)
int monotonic_pthread_cond_init(pthread_cond_t &cond)
void wait(unique_lock< mutex > &m, predicate_type pred)


roscpp
Author(s): Morgan Quigley, Josh Faust, Brian Gerkey, Troy Straszheim
autogenerated on Sun Feb 3 2019 03:29:54