]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/thread/doc/condition_variables.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / thread / doc / condition_variables.qbk
1 [/
2 (C) Copyright 2007-11 Anthony Williams.
3 (C) Copyright 2011-12 Vicente J. Botet Escriba.
4 Distributed under the Boost Software License, Version 1.0.
5 (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt).
7 ]
8
9 [section:condvar_ref Condition Variables]
10
11 [heading Synopsis]
12
13 namespace boost
14 {
15 enum class cv_status;
16 {
17 no_timeout,
18 timeout
19 };
20 class condition_variable;
21 class condition_variable_any;
22 void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
23 }
24
25 The classes `condition_variable` and `condition_variable_any` provide a
26 mechanism for one thread to wait for notification from another thread that a
27 particular condition has become true. The general usage pattern is that one
28 thread locks a mutex and then calls `wait` on an instance of
29 `condition_variable` or `condition_variable_any`. When the thread is woken from
30 the wait, then it checks to see if the appropriate condition is now true, and
31 continues if so. If the condition is not true, then the thread then calls `wait`
32 again to resume waiting. In the simplest case, this condition is just a boolean
33 variable:
34
35 boost::condition_variable cond;
36 boost::mutex mut;
37 bool data_ready;
38
39 void process_data();
40
41 void wait_for_data_to_process()
42 {
43 boost::unique_lock<boost::mutex> lock(mut);
44 while(!data_ready)
45 {
46 cond.wait(lock);
47 }
48 process_data();
49 }
50
51 Notice that the `lock` is passed to `wait`: `wait` will atomically add the
52 thread to the set of threads waiting on the condition variable, and unlock the
53 mutex. When the thread is woken, the mutex will be locked again before the call
54 to `wait` returns. This allows other threads to acquire the mutex in order to
55 update the shared data, and ensures that the data associated with the condition
56 is correctly synchronized.
57
58 In the mean time, another thread sets the condition to `true`, and then calls
59 either `notify_one` or `notify_all` on the condition variable to wake one
60 waiting thread or all the waiting threads respectively.
61
62 void retrieve_data();
63 void prepare_data();
64
65 void prepare_data_for_processing()
66 {
67 retrieve_data();
68 prepare_data();
69 {
70 boost::lock_guard<boost::mutex> lock(mut);
71 data_ready=true;
72 }
73 cond.notify_one();
74 }
75
76 Note that the same mutex is locked before the shared data is updated, but that
77 the mutex does not have to be locked across the call to `notify_one`.
78
79 This example uses an object of type `condition_variable`, but would work just as
80 well with an object of type `condition_variable_any`: `condition_variable_any`
81 is more general, and will work with any kind of lock or mutex, whereas
82 `condition_variable` requires that the lock passed to `wait` is an instance of
83 `boost::unique_lock<boost::mutex>`. This enables `condition_variable` to make
84 optimizations in some cases, based on the knowledge of the mutex type;
85 `condition_variable_any` typically has a more complex implementation than
86 `condition_variable`.
87
88 [section:condition_variable Class `condition_variable`]
89
90 //#include <boost/thread/condition_variable.hpp>
91
92 namespace boost
93 {
94 class condition_variable
95 {
96 public:
97 condition_variable();
98 ~condition_variable();
99
100 void notify_one() noexcept;
101 void notify_all() noexcept;
102
103 void wait(boost::unique_lock<boost::mutex>& lock);
104
105 template<typename predicate_type>
106 void wait(boost::unique_lock<boost::mutex>& lock,predicate_type predicate);
107
108 template <class Clock, class Duration>
109 typename cv_status::type
110 wait_until(
111 unique_lock<mutex>& lock,
112 const chrono::time_point<Clock, Duration>& t);
113
114 template <class Clock, class Duration, class Predicate>
115 bool
116 wait_until(
117 unique_lock<mutex>& lock,
118 const chrono::time_point<Clock, Duration>& t,
119 Predicate pred);
120
121 template <class Rep, class Period>
122 typename cv_status::type
123 wait_for(
124 unique_lock<mutex>& lock,
125 const chrono::duration<Rep, Period>& d);
126
127 template <class Rep, class Period, class Predicate>
128 bool
129 wait_for(
130 unique_lock<mutex>& lock,
131 const chrono::duration<Rep, Period>& d,
132 Predicate pred);
133
134 #if defined BOOST_THREAD_USES_DATETIME
135 bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time);
136 template<typename duration_type>
137 bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time);
138 template<typename predicate_type>
139 bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time,predicate_type predicate);
140 template<typename duration_type,typename predicate_type>
141 bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time,predicate_type predicate);
142 bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time);
143
144 template<typename predicate_type>
145 bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time,predicate_type predicate);
146 #endif
147
148 };
149 }
150
151 [section:constructor `condition_variable()`]
152
153 [variablelist
154
155 [[Effects:] [Constructs an object of class `condition_variable`.]]
156
157 [[Throws:] [__thread_resource_error__ if an error occurs.]]
158
159 ]
160
161 [endsect]
162
163 [section:destructor `~condition_variable()`]
164
165 [variablelist
166
167 [[Precondition:] [All threads waiting on `*this` have been notified by a call to
168 `notify_one` or `notify_all` (though the respective calls to `wait` or
169 `timed_wait` need not have returned).]]
170
171 [[Effects:] [Destroys the object.]]
172
173 [[Throws:] [Nothing.]]
174
175 ]
176
177 [endsect]
178
179 [section:notify_one `void notify_one()`]
180
181 [variablelist
182
183 [[Effects:] [If any threads are currently __blocked__ waiting on `*this` in a call
184 to `wait` or `timed_wait`, unblocks one of those threads.]]
185
186 [[Throws:] [Nothing.]]
187
188 ]
189
190 [endsect]
191
192 [section:notify_all `void notify_all()`]
193
194 [variablelist
195
196 [[Effects:] [If any threads are currently __blocked__ waiting on `*this` in a call
197 to `wait` or `timed_wait`, unblocks all of those threads.]]
198
199 [[Throws:] [Nothing.]]
200
201 ]
202
203 [endsect]
204
205 [section:wait `void wait(boost::unique_lock<boost::mutex>& lock)`]
206
207 [variablelist
208
209 [[Precondition:] [`lock` is locked by the current thread, and either no other
210 thread is currently waiting on `*this`, or the execution of the `mutex()` member
211 function on the `lock` objects supplied in the calls to `wait` or `timed_wait`
212 in all the threads currently waiting on `*this` would return the same value as
213 `lock->mutex()` for this call to `wait`.]]
214
215 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
216 thread will unblock when notified by a call to `this->notify_one()` or
217 `this->notify_all()`, or spuriously. When the thread is unblocked (for whatever
218 reason), the lock is reacquired by invoking `lock.lock()` before the call to
219 `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
220 function exits with an exception.]]
221
222 [[Postcondition:] [`lock` is locked by the current thread.]]
223
224 [[Throws:] [__thread_resource_error__ if an error
225 occurs. __thread_interrupted__ if the wait was interrupted by a call to
226 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
227
228 ]
229
230 [endsect]
231
232 [section:wait_predicate `template<typename predicate_type> void wait(boost::unique_lock<boost::mutex>& lock, predicate_type pred)`]
233
234 [variablelist
235
236 [[Effects:] [As-if ``
237 while(!pred())
238 {
239 wait(lock);
240 }
241 ``]]
242
243 ]
244
245 [endsect]
246
247 [section:timed_wait `bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time)`]
248
249 [variablelist
250
251 [[Precondition:] [`lock` is locked by the current thread, and either no other
252 thread is currently waiting on `*this`, or the execution of the `mutex()` member
253 function on the `lock` objects supplied in the calls to `wait` or `timed_wait`
254 in all the threads currently waiting on `*this` would return the same value as
255 `lock->mutex()` for this call to `wait`.]]
256
257 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
258 thread will unblock when notified by a call to `this->notify_one()` or
259 `this->notify_all()`, when the time as reported by `boost::get_system_time()`
260 would be equal to or later than the specified `abs_time`, or spuriously. When
261 the thread is unblocked (for whatever reason), the lock is reacquired by
262 invoking `lock.lock()` before the call to `wait` returns. The lock is also
263 reacquired by invoking `lock.lock()` if the function exits with an exception.]]
264
265 [[Returns:] [`false` if the call is returning because the time specified by
266 `abs_time` was reached, `true` otherwise.]]
267
268 [[Postcondition:] [`lock` is locked by the current thread.]]
269
270 [[Throws:] [__thread_resource_error__ if an error
271 occurs. __thread_interrupted__ if the wait was interrupted by a call to
272 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
273
274 ]
275
276 [endsect]
277
278 [section:timed_wait_rel `template<typename duration_type> bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time)`]
279
280 [variablelist
281
282 [[Precondition:] [`lock` is locked by the current thread, and either no other
283 thread is currently waiting on `*this`, or the execution of the `mutex()` member
284 function on the `lock` objects supplied in the calls to `wait` or `timed_wait`
285 in all the threads currently waiting on `*this` would return the same value as
286 `lock->mutex()` for this call to `wait`.]]
287
288 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
289 thread will unblock when notified by a call to `this->notify_one()` or
290 `this->notify_all()`, after the period of time indicated by the `rel_time`
291 argument has elapsed, or spuriously. When the thread is unblocked (for whatever
292 reason), the lock is reacquired by invoking `lock.lock()` before the call to
293 `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
294 function exits with an exception.]]
295
296 [[Returns:] [`false` if the call is returning because the time period specified
297 by `rel_time` has elapsed, `true` otherwise.]]
298
299 [[Postcondition:] [`lock` is locked by the current thread.]]
300
301 [[Throws:] [__thread_resource_error__ if an error
302 occurs. __thread_interrupted__ if the wait was interrupted by a call to
303 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
304
305 ]
306
307 [note The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.]
308
309 [endsect]
310
311 [section:timed_wait_predicate `template<typename predicate_type> bool timed_wait(boost::unique_lock<boost::mutex>& lock, boost::system_time const& abs_time, predicate_type pred)`]
312
313 [variablelist
314
315 [[Effects:] [As-if ``
316 while(!pred())
317 {
318 if(!timed_wait(lock,abs_time))
319 {
320 return pred();
321 }
322 }
323 return true;
324 ``]]
325
326 ]
327
328 [endsect]
329
330
331 [section:wait_until `template <class Clock, class Duration> cv_status wait_until(boost::unique_lock<boost::mutex>& lock, const chrono::time_point<Clock, Duration>& abs_time)`]
332
333 [variablelist
334
335 [[Precondition:] [`lock` is locked by the current thread, and either no other
336 thread is currently waiting on `*this`, or the execution of the `mutex()` member
337 function on the `lock` objects supplied in the calls to `wait` or `wait_for` or `wait_until`
338 in all the threads currently waiting on `*this` would return the same value as
339 `lock->mutex()` for this call to `wait`.]]
340
341 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
342 thread will unblock when notified by a call to `this->notify_one()` or
343 `this->notify_all()`, when the time as reported by `Clock::now()`
344 would be equal to or later than the specified `abs_time`, or spuriously. When
345 the thread is unblocked (for whatever reason), the lock is reacquired by
346 invoking `lock.lock()` before the call to `wait` returns. The lock is also
347 reacquired by invoking `lock.lock()` if the function exits with an exception.]]
348
349 [[Returns:] [`cv_status::timeout` if the call is returning because the time specified by
350 `abs_time` was reached, `cv_status::no_timeout` otherwise.]]
351
352 [[Postcondition:] [`lock` is locked by the current thread.]]
353
354 [[Throws:] [__thread_resource_error__ if an error
355 occurs. __thread_interrupted__ if the wait was interrupted by a call to
356 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
357
358 ]
359
360 [endsect]
361
362 [section:wait_for `template <class Rep, class Period> cv_status wait_for(boost::unique_lock<boost::mutex>& lock, const chrono::duration<Rep, Period>& rel_time)`]
363
364
365 [variablelist
366
367 [[Precondition:] [`lock` is locked by the current thread, and either no other
368 thread is currently waiting on `*this`, or the execution of the `mutex()` member
369 function on the `lock` objects supplied in the calls to `wait` or `wait_until` or `wait_for`
370 in all the threads currently waiting on `*this` would return the same value as
371 `lock->mutex()` for this call to `wait`.]]
372
373 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
374 thread will unblock when notified by a call to `this->notify_one()` or
375 `this->notify_all()`, after the period of time indicated by the `rel_time`
376 argument has elapsed, or spuriously. When the thread is unblocked (for whatever
377 reason), the lock is reacquired by invoking `lock.lock()` before the call to
378 `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
379 function exits with an exception.]]
380
381 [[Returns:] [`cv_status::timeout ` if the call is returning because the time period specified
382 by `rel_time` has elapsed, `cv_status::no_timeout ` otherwise.]]
383
384 [[Postcondition:] [`lock` is locked by the current thread.]]
385
386 [[Throws:] [__thread_resource_error__ if an error
387 occurs. __thread_interrupted__ if the wait was interrupted by a call to
388 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
389
390 ]
391
392 [note The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.]
393
394 [endsect]
395
396 [section:wait_until_predicate `template <class Clock, class Duration, class Predicate> bool wait_until(boost::unique_lock<boost::mutex>& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred)`]
397
398
399 [variablelist
400
401 [[Effects:] [As-if ``
402 while(!pred())
403 {
404 if(!wait_until(lock,abs_time))
405 {
406 return pred();
407 }
408 }
409 return true;
410 ``]]
411
412 ]
413
414 [endsect]
415
416 [section:wait_for_predicate `template <class Rep, class Period, class Predicate> bool wait_for(boost::unique_lock<boost::mutex>& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred)`]
417
418
419 [variablelist
420
421 [[Effects:] [As-if ``
422 return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
423 ``]]
424
425 ]
426
427 [endsect]
428
429
430
431
432 [endsect]
433
434 [section:condition_variable_any Class `condition_variable_any`]
435
436 //#include <boost/thread/condition_variable.hpp>
437
438 namespace boost
439 {
440 class condition_variable_any
441 {
442 public:
443 condition_variable_any();
444 ~condition_variable_any();
445
446 void notify_one();
447 void notify_all();
448
449 template<typename lock_type>
450 void wait(lock_type& lock);
451
452 template<typename lock_type,typename predicate_type>
453 void wait(lock_type& lock,predicate_type predicate);
454
455 template <class lock_type, class Clock, class Duration>
456 cv_status wait_until(
457 lock_type& lock,
458 const chrono::time_point<Clock, Duration>& t);
459
460 template <class lock_type, class Clock, class Duration, class Predicate>
461 bool wait_until(
462 lock_type& lock,
463 const chrono::time_point<Clock, Duration>& t,
464 Predicate pred);
465
466
467 template <class lock_type, class Rep, class Period>
468 cv_status wait_for(
469 lock_type& lock,
470 const chrono::duration<Rep, Period>& d);
471
472 template <class lock_type, class Rep, class Period, class Predicate>
473 bool wait_for(
474 lock_type& lock,
475 const chrono::duration<Rep, Period>& d,
476 Predicate pred);
477
478 #if defined BOOST_THREAD_USES_DATETIME
479 template<typename lock_type>
480 bool timed_wait(lock_type& lock,boost::system_time const& abs_time);
481 template<typename lock_type,typename duration_type>
482 bool timed_wait(lock_type& lock,duration_type const& rel_time);
483 template<typename lock_type,typename predicate_type>
484 bool timed_wait(lock_type& lock,boost::system_time const& abs_time,predicate_type predicate);
485 template<typename lock_type,typename duration_type,typename predicate_type>
486 bool timed_wait(lock_type& lock,duration_type const& rel_time,predicate_type predicate);
487 template<typename lock_type>
488 bool timed_wait(lock_type>& lock,boost::xtime const& abs_time);
489 template<typename lock_type,typename predicate_type>
490 bool timed_wait(lock_type& lock,boost::xtime const& abs_time,predicate_type predicate);
491 #endif
492 };
493 }
494
495 [section:constructor `condition_variable_any()`]
496
497 [variablelist
498
499 [[Effects:] [Constructs an object of class `condition_variable_any`.]]
500
501 [[Throws:] [__thread_resource_error__ if an error occurs.]]
502
503 ]
504
505 [endsect]
506
507 [section:destructor `~condition_variable_any()`]
508
509 [variablelist
510
511 [[Precondition:] [All threads waiting on `*this` have been notified by a call to
512 `notify_one` or `notify_all` (though the respective calls to `wait` or
513 `timed_wait` need not have returned).]]
514
515 [[Effects:] [Destroys the object.]]
516
517 [[Throws:] [Nothing.]]
518
519 ]
520
521 [endsect]
522
523 [section:notify_one `void notify_one()`]
524
525 [variablelist
526
527 [[Effects:] [If any threads are currently __blocked__ waiting on `*this` in a call
528 to `wait` or `timed_wait`, unblocks one of those threads.]]
529
530 [[Throws:] [Nothing.]]
531
532 ]
533
534 [endsect]
535
536 [section:notify_all `void notify_all()`]
537
538 [variablelist
539
540 [[Effects:] [If any threads are currently __blocked__ waiting on `*this` in a call
541 to `wait` or `timed_wait`, unblocks all of those threads.]]
542
543 [[Throws:] [Nothing.]]
544
545 ]
546
547 [endsect]
548
549 [section:wait `template<typename lock_type> void wait(lock_type& lock)`]
550
551 [variablelist
552
553 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
554 thread will unblock when notified by a call to `this->notify_one()` or
555 `this->notify_all()`, or spuriously. When the thread is unblocked (for whatever
556 reason), the lock is reacquired by invoking `lock.lock()` before the call to
557 `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
558 function exits with an exception.]]
559
560 [[Postcondition:] [`lock` is locked by the current thread.]]
561
562 [[Throws:] [__thread_resource_error__ if an error
563 occurs. __thread_interrupted__ if the wait was interrupted by a call to
564 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
565
566 ]
567
568 [endsect]
569
570 [section:wait_predicate `template<typename lock_type,typename predicate_type> void wait(lock_type& lock, predicate_type pred)`]
571
572 [variablelist
573
574 [[Effects:] [As-if ``
575 while(!pred())
576 {
577 wait(lock);
578 }
579 ``]]
580
581 ]
582
583 [endsect]
584
585 [section:timed_wait `template<typename lock_type> bool timed_wait(lock_type& lock,boost::system_time const& abs_time)`]
586
587 [variablelist
588
589 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
590 thread will unblock when notified by a call to `this->notify_one()` or
591 `this->notify_all()`, when the time as reported by `boost::get_system_time()`
592 would be equal to or later than the specified `abs_time`, or spuriously. When
593 the thread is unblocked (for whatever reason), the lock is reacquired by
594 invoking `lock.lock()` before the call to `wait` returns. The lock is also
595 reacquired by invoking `lock.lock()` if the function exits with an exception.]]
596
597 [[Returns:] [`false` if the call is returning because the time specified by
598 `abs_time` was reached, `true` otherwise.]]
599
600 [[Postcondition:] [`lock` is locked by the current thread.]]
601
602 [[Throws:] [__thread_resource_error__ if an error
603 occurs. __thread_interrupted__ if the wait was interrupted by a call to
604 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
605
606 ]
607
608 [endsect]
609
610 [section:timed_wait_rel `template<typename lock_type,typename duration_type> bool timed_wait(lock_type& lock,duration_type const& rel_time)`]
611
612 [variablelist
613
614 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
615 thread will unblock when notified by a call to `this->notify_one()` or
616 `this->notify_all()`, after the period of time indicated by the `rel_time`
617 argument has elapsed, or spuriously. When the thread is unblocked (for whatever
618 reason), the lock is reacquired by invoking `lock.lock()` before the call to
619 `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
620 function exits with an exception.]]
621
622 [[Returns:] [`false` if the call is returning because the time period specified
623 by `rel_time` has elapsed, `true` otherwise.]]
624
625 [[Postcondition:] [`lock` is locked by the current thread.]]
626
627 [[Throws:] [__thread_resource_error__ if an error
628 occurs. __thread_interrupted__ if the wait was interrupted by a call to
629 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
630
631 ]
632
633 [note The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.]
634
635 [endsect]
636
637 [section:timed_wait_predicate `template<typename lock_type,typename predicate_type> bool timed_wait(lock_type& lock, boost::system_time const& abs_time, predicate_type pred)`]
638
639 [variablelist
640
641 [[Effects:] [As-if ``
642 while(!pred())
643 {
644 if(!timed_wait(lock,abs_time))
645 {
646 return pred();
647 }
648 }
649 return true;
650 ``]]
651
652 ]
653
654 [endsect]
655
656 [section:wait_until `template <class lock_type, class Clock, class Duration> cv_status wait_until(lock_type& lock, const chrono::time_point<Clock, Duration>& abs_time)`]
657
658 [variablelist
659
660 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
661 thread will unblock when notified by a call to `this->notify_one()` or
662 `this->notify_all()`, when the time as reported by `Clock::now()`
663 would be equal to or later than the specified `abs_time`, or spuriously. When
664 the thread is unblocked (for whatever reason), the lock is reacquired by
665 invoking `lock.lock()` before the call to `wait` returns. The lock is also
666 reacquired by invoking `lock.lock()` if the function exits with an exception.]]
667
668 [[Returns:] [`cv_status::timeout` if the call is returning because the time specified by
669 `abs_time` was reached, `cv_status::no_timeout` otherwise.]]
670
671 [[Postcondition:] [`lock` is locked by the current thread.]]
672
673 [[Throws:] [__thread_resource_error__ if an error
674 occurs. __thread_interrupted__ if the wait was interrupted by a call to
675 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
676
677 ]
678
679 [endsect]
680
681 [section:wait_for `template <class lock_type, class Rep, class Period> cv_status wait_for(lock_type& lock, const chrono::duration<Rep, Period>& rel_time)`]
682
683 [variablelist
684
685 [[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
686 thread will unblock when notified by a call to `this->notify_one()` or
687 `this->notify_all()`, after the period of time indicated by the `rel_time`
688 argument has elapsed, or spuriously. When the thread is unblocked (for whatever
689 reason), the lock is reacquired by invoking `lock.lock()` before the call to
690 `wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
691 function exits with an exception.]]
692
693 [[Returns:] [`cv_status::timeout` if the call is returning because the time specified by
694 `abs_time` was reached, `cv_status::no_timeout` otherwise.]]
695
696 [[Postcondition:] [`lock` is locked by the current thread.]]
697
698 [[Throws:] [__thread_resource_error__ if an error
699 occurs. __thread_interrupted__ if the wait was interrupted by a call to
700 __interrupt__ on the __thread__ object associated with the current thread of execution.]]
701
702 ]
703
704 [note The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.]
705
706 [endsect]
707
708 [section:wait_until_predicate `template <class lock_type, class Clock, class Duration, class Predicate> bool wait_until(lock_type& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred)`]
709
710 [variablelist
711
712 [[Effects:] [As-if ``
713 while(!pred())
714 {
715 if(!__cvany_wait_until(lock,abs_time))
716 {
717 return pred();
718 }
719 }
720 return true;
721 ``]]
722
723 ]
724
725 [endsect]
726
727 [section:wait_for_predicate `template <class lock_type, class Rep, class Period, class Predicate> bool wait_for(lock_type& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred)`]
728
729 [variablelist
730
731 [[Effects:] [As-if ``
732 return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
733 ``]]
734
735 ]
736
737 [endsect]
738
739 [endsect]
740
741 [section:condition Typedef `condition` DEPRECATED V3]
742
743 // #include <boost/thread/condition.hpp>
744 namespace boost
745 {
746
747 typedef condition_variable_any condition;
748
749 }
750
751 The typedef `condition` is provided for backwards compatibility with previous boost releases.
752
753 [endsect]
754
755
756 [section:notify_all_at_thread_exit Non-member Function `notify_all_at_thread_exit`()]
757
758 // #include <boost/thread/condition_variable.hpp>
759
760 namespace boost
761 {
762 void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
763 }
764
765 [variablelist
766
767 [[Requires:] [`lk` is locked by the calling thread and either no other thread is waiting on `cond`, or `lk.mutex()` returns the same value for each of the lock arguments supplied by all concurrently waiting (via `wait`, `wait_for`, or `wait_until`) threads.]]
768 [[Effects:] [transfers ownership of the lock associated with `lk` into internal storage and schedules `cond` to be notified when the current thread exits, after all objects of thread storage duration associated with the current thread have been destroyed. This notification shall be as if
769
770 ``
771 lk.unlock();
772 cond.notify_all();
773 ``
774
775 ]]
776
777 ]
778
779 [/
780 [[Synchronization:] [The call to notify_all_at_thread_exit and the completion of the destructors for all the current threadÕs variables of thread storage duration synchronize with (1.10) calls to functions waiting on cond.
781 ]]
782 [[Note:] [The supplied lock will be held until the thread exits, and care must be taken to ensure that this does not cause deadlock due to lock ordering issues. After calling notify_all_at_thread_exit it is recommended that the thread should be exited as soon as possible, and that no blocking or time-consuming tasks are run on that thread.
783 ]]
784 [[Note:] [It is the userÕs responsibility to ensure that waiting threads do not erroneously assume that the thread has finished if they experience spurious wakeups. This typically requires that the condition being waited for is satisfied while holding the lock on lk, and that this lock is not released and reacquired prior to calling notify_all_at_thread_exit.
785 ]]
786 ]
787
788 [endsect]
789
790 [endsect]