From Jason Turner

[thread.condition]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpgysjhk9l/{from.md → to.md} +74 -104
tmp/tmpgysjhk9l/{from.md → to.md} RENAMED
@@ -18,13 +18,14 @@ three atomic parts:
18
 
19
  1. the release of the mutex and entry into the waiting state;
20
  2. the unblocking of the wait; and
21
  3. the reacquisition of the lock.
22
 
23
- The implementation shall behave as if `notify_one`, `notify_all`, and
24
- each part of the `wait`, `wait_for`, and `wait_until` executions are
25
- executed in some unspecified total order.
 
26
 
27
  Condition variable construction and destruction need not be
28
  synchronized.
29
 
30
  ``` cpp
@@ -58,14 +59,13 @@ as if
58
  ``` cpp
59
  lk.unlock();
60
  cond.notify_all();
61
  ```
62
 
63
- *Synchronization:* The call to `notify_all_at_thread_exit` and the
64
- completion of the destructors for all the current thread’s variables of
65
- thread storage duration synchronize with ([[intro.multithread]]) calls
66
- to functions waiting on `cond`.
67
 
68
  *Note:* The supplied lock will be held until the thread exits, and care
69
  must be taken to ensure that this does not cause deadlock due to lock
70
  ordering issues. After calling `notify_all_at_thread_exit` it is
71
  recommended that the thread should be exited as soon as possible, and
@@ -171,32 +171,29 @@ void wait(unique_lock<mutex>& lock);
171
  `lock.owns_lock()` is `true` and `lock.mutex()` is locked by the calling
172
  thread, and either
173
 
174
  - no other thread is waiting on this `condition_variable` object or
175
  - `lock.mutex()` returns the same value for each of the `lock` arguments
176
- supplied by all concurrently waiting (via `wait` or `timed_wait`)
177
- threads.
178
 
179
  *Effects:*
180
 
181
  - Atomically calls `lock.unlock()` and blocks on `*this`.
182
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock),
183
  then returns.
184
  - The function will unblock when signaled by a call to `notify_one()` or
185
  a call to `notify_all()`, or spuriously.
186
- - If the function exits via an exception, `lock.lock()` shall be called
187
- prior to exiting the function scope.
 
 
188
 
189
  `lock.owns_lock()` is `true` and `lock.mutex()` is locked by the calling
190
  thread.
191
 
192
- *Throws:* `system_error` when an exception is
193
- required ([[thread.req.exception]]).
194
-
195
- *Error conditions:*
196
-
197
- - equivalent error condition from `lock.lock()` or `lock.unlock()`.
198
 
199
  ``` cpp
200
  template <class Predicate>
201
  void wait(unique_lock<mutex>& lock, Predicate pred);
202
  ```
@@ -204,29 +201,29 @@ template <class Predicate>
204
  *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
205
  the calling thread, and either
206
 
207
  - no other thread is waiting on this `condition_variable` object or
208
  - `lock.mutex()` returns the same value for each of the `lock` arguments
209
- supplied by all concurrently waiting (via `wait` or `timed_wait`)
210
- threads.
211
 
212
- *Effects:*
213
 
214
  ``` cpp
215
  while (!pred())
216
  wait(lock);
217
  ```
218
 
 
 
 
 
219
  `lock.owns_lock()` is `true` and `lock.mutex()` is locked by the calling
220
  thread.
221
 
222
- *Throws:* `std::system_error` when an exception is
223
- required ([[thread.req.exception]]).
224
-
225
- *Error conditions:*
226
-
227
- - equivalent error condition from `lock.lock()` or `lock.unlock()`.
228
 
229
  ``` cpp
230
  template <class Clock, class Duration>
231
  cv_status wait_until(unique_lock<mutex>& lock,
232
  const chrono::time_point<Clock, Duration>& abs_time);
@@ -248,25 +245,24 @@ thread, and either
248
  - The function will unblock when signaled by a call to `notify_one()`, a
249
  call to `notify_all()`, expiration of the absolute
250
  timeout ([[thread.req.timing]]) specified by `abs_time`, or
251
  spuriously.
252
  - If the function exits via an exception, `lock.lock()` shall be called
253
- prior to exiting the function scope.
 
 
 
 
254
 
255
  `lock.owns_lock()` is `true` and `lock.mutex()` is locked by the calling
256
  thread.
257
 
258
  *Returns:* `cv_status::timeout` if the absolute
259
  timeout ([[thread.req.timing]]) specified by `abs_time` expired,
260
  otherwise `cv_status::no_timeout`.
261
 
262
- *Throws:* `system_error` when an exception is
263
- required ([[thread.req.exception]]).
264
-
265
- *Error conditions:*
266
-
267
- - equivalent error condition from `lock.lock()` or `lock.unlock()`.
268
 
269
  ``` cpp
270
  template <class Rep, class Period>
271
  cv_status wait_for(unique_lock<mutex>& lock,
272
  const chrono::duration<Rep, Period>& rel_time);
@@ -278,29 +274,28 @@ thread, and either
278
  - no other thread is waiting on this `condition_variable` object or
279
  - `lock.mutex()` returns the same value for each of the `lock` arguments
280
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
281
  `wait_until`) threads.
282
 
283
- *Effects:* as if
284
 
285
  ``` cpp
286
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
287
  ```
288
 
289
  *Returns:* `cv_status::timeout` if the relative
290
  timeout ([[thread.req.timing]]) specified by `rel_time` expired,
291
  otherwise `cv_status::no_timeout`.
292
 
 
 
 
 
293
  `lock.owns_lock()` is `true` and `lock.mutex()` is locked by the calling
294
  thread.
295
 
296
- *Throws:* `system_error` when an exception is
297
- required ([[thread.req.exception]]).
298
-
299
- *Error conditions:*
300
-
301
- - equivalent error condition from `lock.lock()` or `lock.unlock()`.
302
 
303
  ``` cpp
304
  template <class Clock, class Duration, class Predicate>
305
  bool wait_until(unique_lock<mutex>& lock,
306
  const chrono::time_point<Clock, Duration>& abs_time,
@@ -310,36 +305,34 @@ template <class Clock, class Duration, class Predicate>
310
  *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
311
  the calling thread, and either
312
 
313
  - no other thread is waiting on this `condition_variable` object or
314
  - `lock.mutex()` returns the same value for each of the `lock` arguments
315
- supplied by all concurrently waiting (via `wait` or `timed_wait`)
316
- threads.
317
 
318
- *Effects:*
319
 
320
  ``` cpp
321
  while (!pred())
322
  if (wait_until(lock, abs_time) == cv_status::timeout)
323
  return pred();
324
  return true;
325
  ```
326
 
327
- *Returns:* `pred()`
 
 
328
 
329
  `lock.owns_lock()` is `true` and `lock.mutex()` is locked by the calling
330
  thread.
331
 
332
  The returned value indicates whether the predicate evaluated to `true`
333
  regardless of whether the timeout was triggered.
334
 
335
- *Throws:* `std::system_error` when an exception is
336
- required ([[thread.req.exception]]).
337
-
338
- *Error conditions:*
339
-
340
- - equivalent error condition from `lock.lock()` or `lock.unlock()`.
341
 
342
  ``` cpp
343
  template <class Rep, class Period, class Predicate>
344
  bool wait_for(unique_lock<mutex>& lock,
345
  const chrono::duration<Rep, Period>& rel_time,
@@ -352,33 +345,31 @@ thread, and either
352
  - no other thread is waiting on this `condition_variable` object or
353
  - `lock.mutex()` returns the same value for each of the `lock` arguments
354
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
355
  `wait_until`) threads.
356
 
357
- *Effects:* as if
358
 
359
  ``` cpp
360
  return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));
361
  ```
362
 
363
  There is no blocking if `pred()` is initially `true`, even if the
364
  timeout has already expired.
365
 
 
 
 
 
366
  `lock.owns_lock()` is `true` and `lock.mutex()` is locked by the calling
367
  thread.
368
 
369
- *Returns:* `pred()`
370
-
371
  The returned value indicates whether the predicate evaluates to `true`
372
  regardless of whether the timeout was triggered.
373
 
374
- *Throws:* `system_error` when an exception is
375
- required ([[thread.req.exception]]).
376
-
377
- *Error conditions:*
378
-
379
- - equivalent error condition from `lock.lock()` or `lock.unlock()`.
380
 
381
  ### Class `condition_variable_any` <a id="thread.condition.condvarany">[[thread.condition.condvarany]]</a>
382
 
383
  A `Lock` type shall meet the `BasicLockable` requirements (
384
  [[thread.req.lockable.basic]]). All of the standard mutex types meet
@@ -428,12 +419,12 @@ condition_variable_any();
428
  *Throws:* `bad_alloc` or `system_error` when an exception is
429
  required ([[thread.req.exception]]).
430
 
431
  *Error conditions:*
432
 
433
- - `resource_unavailable_try_again` — if any native handle type
434
- manipulated is not available.
435
  - `operation_not_permitted` — if the thread does not have the privilege
436
  to perform the operation.
437
 
438
  ``` cpp
439
  ~condition_variable_any();
@@ -478,28 +469,25 @@ allows to query that, such as the `unique_lock` wrapper.
478
  - Atomically calls `lock.unlock()` and blocks on `*this`.
479
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock)
480
  and returns.
481
  - The function will unblock when signaled by a call to `notify_one()`, a
482
  call to `notify_all()`, or spuriously.
483
- - If the function exits via an exception, `lock.lock()` shall be called
484
- prior to exiting the function scope.
 
 
485
 
486
  `lock` is locked by the calling thread.
487
 
488
- *Throws:* `system_error` when an exception is
489
- required ([[thread.req.exception]]).
490
-
491
- *Error conditions:*
492
-
493
- - equivalent error condition from `lock.lock()` or `lock.unlock()`.
494
 
495
  ``` cpp
496
  template <class Lock, class Predicate>
497
  void wait(Lock& lock, Predicate pred);
498
  ```
499
 
500
- *Effects:*
501
 
502
  ``` cpp
503
  while (!pred())
504
  wait(lock);
505
  ```
@@ -517,91 +505,73 @@ template <class Lock, class Clock, class Duration>
517
  - The function will unblock when signaled by a call to `notify_one()`, a
518
  call to `notify_all()`, expiration of the absolute
519
  timeout ([[thread.req.timing]]) specified by `abs_time`, or
520
  spuriously.
521
  - If the function exits via an exception, `lock.lock()` shall be called
522
- prior to exiting the function scope.
 
 
 
 
523
 
524
  `lock` is locked by the calling thread.
525
 
526
  *Returns:* `cv_status::timeout` if the absolute
527
  timeout ([[thread.req.timing]]) specified by `abs_time` expired,
528
  otherwise `cv_status::no_timeout`.
529
 
530
- *Throws:* `system_error` when an exception is
531
- required ([[thread.req.exception]]).
532
-
533
- *Error conditions:*
534
-
535
- - equivalent error condition from `lock.lock()` or `lock.unlock()`.
536
 
537
  ``` cpp
538
  template <class Lock, class Rep, class Period>
539
  cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
540
  ```
541
 
542
- *Effects:* as if
543
 
544
  ``` cpp
545
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
546
  ```
547
 
548
  *Returns:* `cv_status::timeout` if the relative
549
  timeout ([[thread.req.timing]]) specified by `rel_time` expired,
550
  otherwise `cv_status::no_timeout`.
551
 
 
 
 
 
552
  `lock` is locked by the calling thread.
553
 
554
- *Throws:* `system_error` when an exception is
555
- required ([[thread.req.exception]]).
556
-
557
- *Error conditions:*
558
-
559
- - equivalent error condition from `lock.lock()` or `lock.unlock()`.
560
 
561
  ``` cpp
562
  template <class Lock, class Clock, class Duration, class Predicate>
563
  bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
564
  ```
565
 
566
- *Effects:*
567
 
568
  ``` cpp
569
  while (!pred())
570
  if (wait_until(lock, abs_time) == cv_status::timeout)
571
  return pred();
572
  return true;
573
  ```
574
 
575
- *Returns:* `pred()`
 
576
 
577
  The returned value indicates whether the predicate evaluates to `true`
578
  regardless of whether the timeout was triggered.
579
 
580
  ``` cpp
581
  template <class Lock, class Rep, class Period, class Predicate>
582
  bool wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred);
583
  ```
584
 
585
- *Effects:* as if
586
 
587
  ``` cpp
588
  return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));
589
  ```
590
 
591
- There is no blocking if `pred()` is initially `true`, even if the
592
- timeout has already expired.
593
-
594
- `lock` is locked by the calling thread.
595
-
596
- *Returns:* `pred()`
597
-
598
- The returned value indicates whether the predicate evaluates to `true`
599
- regardless of whether the timeout was triggered.
600
-
601
- *Throws:* `system_error` when an exception is
602
- required ([[thread.req.exception]]).
603
-
604
- *Error conditions:*
605
-
606
- - equivalent error condition from `lock.lock()` or `lock.unlock()`.
607
-
 
18
 
19
  1. the release of the mutex and entry into the waiting state;
20
  2. the unblocking of the wait; and
21
  3. the reacquisition of the lock.
22
 
23
+ The implementation shall behave as if all executions of `notify_one`,
24
+ `notify_all`, and each part of the `wait`, `wait_for`, and `wait_until`
25
+ executions are executed in a single unspecified total order consistent
26
+ with the "happens before" order.
27
 
28
  Condition variable construction and destruction need not be
29
  synchronized.
30
 
31
  ``` cpp
 
59
  ``` cpp
60
  lk.unlock();
61
  cond.notify_all();
62
  ```
63
 
64
+ *Synchronization:* The implied `lk.unlock()` call is sequenced after the
65
+ destruction of all objects with thread storage duration associated with
66
+ the current thread.
 
67
 
68
  *Note:* The supplied lock will be held until the thread exits, and care
69
  must be taken to ensure that this does not cause deadlock due to lock
70
  ordering issues. After calling `notify_all_at_thread_exit` it is
71
  recommended that the thread should be exited as soon as possible, and
 
171
  `lock.owns_lock()` is `true` and `lock.mutex()` is locked by the calling
172
  thread, and either
173
 
174
  - no other thread is waiting on this `condition_variable` object or
175
  - `lock.mutex()` returns the same value for each of the `lock` arguments
176
+ supplied by all concurrently waiting (via `wait`, `wait_for`, or
177
+ `wait_until`) threads.
178
 
179
  *Effects:*
180
 
181
  - Atomically calls `lock.unlock()` and blocks on `*this`.
182
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock),
183
  then returns.
184
  - The function will unblock when signaled by a call to `notify_one()` or
185
  a call to `notify_all()`, or spuriously.
186
+
187
+ *Remarks:* If the function fails to meet the postcondition,
188
+ `std::terminate()` shall be called ([[except.terminate]]). This can
189
+ happen if the re-locking of the mutex throws an exception.
190
 
191
  `lock.owns_lock()` is `true` and `lock.mutex()` is locked by the calling
192
  thread.
193
 
194
+ *Throws:* Nothing.
 
 
 
 
 
195
 
196
  ``` cpp
197
  template <class Predicate>
198
  void wait(unique_lock<mutex>& lock, Predicate pred);
199
  ```
 
201
  *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
202
  the calling thread, and either
203
 
204
  - no other thread is waiting on this `condition_variable` object or
205
  - `lock.mutex()` returns the same value for each of the `lock` arguments
206
+ supplied by all concurrently waiting (via `wait`, `wait_for`, or
207
+ `wait_until`) threads.
208
 
209
+ *Effects:* Equivalent to:
210
 
211
  ``` cpp
212
  while (!pred())
213
  wait(lock);
214
  ```
215
 
216
+ *Remarks:* If the function fails to meet the postcondition,
217
+ `std::terminate()` shall be called ([[except.terminate]]). This can
218
+ happen if the re-locking of the mutex throws an exception.
219
+
220
  `lock.owns_lock()` is `true` and `lock.mutex()` is locked by the calling
221
  thread.
222
 
223
+ *Throws:* Timeout-related exceptions ([[thread.req.timing]]) or any
224
+ exception thrown by `pred`.
 
 
 
 
225
 
226
  ``` cpp
227
  template <class Clock, class Duration>
228
  cv_status wait_until(unique_lock<mutex>& lock,
229
  const chrono::time_point<Clock, Duration>& abs_time);
 
245
  - The function will unblock when signaled by a call to `notify_one()`, a
246
  call to `notify_all()`, expiration of the absolute
247
  timeout ([[thread.req.timing]]) specified by `abs_time`, or
248
  spuriously.
249
  - If the function exits via an exception, `lock.lock()` shall be called
250
+ prior to exiting the function.
251
+
252
+ *Remarks:* If the function fails to meet the postcondition,
253
+ `std::terminate()` shall be called ([[except.terminate]]). This can
254
+ happen if the re-locking of the mutex throws an exception.
255
 
256
  `lock.owns_lock()` is `true` and `lock.mutex()` is locked by the calling
257
  thread.
258
 
259
  *Returns:* `cv_status::timeout` if the absolute
260
  timeout ([[thread.req.timing]]) specified by `abs_time` expired,
261
  otherwise `cv_status::no_timeout`.
262
 
263
+ *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
 
 
 
 
 
264
 
265
  ``` cpp
266
  template <class Rep, class Period>
267
  cv_status wait_for(unique_lock<mutex>& lock,
268
  const chrono::duration<Rep, Period>& rel_time);
 
274
  - no other thread is waiting on this `condition_variable` object or
275
  - `lock.mutex()` returns the same value for each of the `lock` arguments
276
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
277
  `wait_until`) threads.
278
 
279
+ *Effects:* Equivalent to:
280
 
281
  ``` cpp
282
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
283
  ```
284
 
285
  *Returns:* `cv_status::timeout` if the relative
286
  timeout ([[thread.req.timing]]) specified by `rel_time` expired,
287
  otherwise `cv_status::no_timeout`.
288
 
289
+ *Remarks:* If the function fails to meet the postcondition,
290
+ `std::terminate()` shall be called ([[except.terminate]]). This can
291
+ happen if the re-locking of the mutex throws an exception.
292
+
293
  `lock.owns_lock()` is `true` and `lock.mutex()` is locked by the calling
294
  thread.
295
 
296
+ *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
 
 
 
 
 
297
 
298
  ``` cpp
299
  template <class Clock, class Duration, class Predicate>
300
  bool wait_until(unique_lock<mutex>& lock,
301
  const chrono::time_point<Clock, Duration>& abs_time,
 
305
  *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
306
  the calling thread, and either
307
 
308
  - no other thread is waiting on this `condition_variable` object or
309
  - `lock.mutex()` returns the same value for each of the `lock` arguments
310
+ supplied by all concurrently waiting (via `wait`, `wait_for`, or
311
+ `wait_until`) threads.
312
 
313
+ *Effects:* Equivalent to:
314
 
315
  ``` cpp
316
  while (!pred())
317
  if (wait_until(lock, abs_time) == cv_status::timeout)
318
  return pred();
319
  return true;
320
  ```
321
 
322
+ *Remarks:* If the function fails to meet the postcondition,
323
+ `std::terminate()` shall be called ([[except.terminate]]). This can
324
+ happen if the re-locking of the mutex throws an exception.
325
 
326
  `lock.owns_lock()` is `true` and `lock.mutex()` is locked by the calling
327
  thread.
328
 
329
  The returned value indicates whether the predicate evaluated to `true`
330
  regardless of whether the timeout was triggered.
331
 
332
+ *Throws:* Timeout-related exceptions ([[thread.req.timing]]) or any
333
+ exception thrown by `pred`.
 
 
 
 
334
 
335
  ``` cpp
336
  template <class Rep, class Period, class Predicate>
337
  bool wait_for(unique_lock<mutex>& lock,
338
  const chrono::duration<Rep, Period>& rel_time,
 
345
  - no other thread is waiting on this `condition_variable` object or
346
  - `lock.mutex()` returns the same value for each of the `lock` arguments
347
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
348
  `wait_until`) threads.
349
 
350
+ *Effects:* Equivalent to:
351
 
352
  ``` cpp
353
  return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));
354
  ```
355
 
356
  There is no blocking if `pred()` is initially `true`, even if the
357
  timeout has already expired.
358
 
359
+ *Remarks:* If the function fails to meet the postcondition,
360
+ `std::terminate()` shall be called ([[except.terminate]]). This can
361
+ happen if the re-locking of the mutex throws an exception.
362
+
363
  `lock.owns_lock()` is `true` and `lock.mutex()` is locked by the calling
364
  thread.
365
 
 
 
366
  The returned value indicates whether the predicate evaluates to `true`
367
  regardless of whether the timeout was triggered.
368
 
369
+ *Throws:* Timeout-related exceptions ([[thread.req.timing]]) or any
370
+ exception thrown by `pred`.
 
 
 
 
371
 
372
  ### Class `condition_variable_any` <a id="thread.condition.condvarany">[[thread.condition.condvarany]]</a>
373
 
374
  A `Lock` type shall meet the `BasicLockable` requirements (
375
  [[thread.req.lockable.basic]]). All of the standard mutex types meet
 
419
  *Throws:* `bad_alloc` or `system_error` when an exception is
420
  required ([[thread.req.exception]]).
421
 
422
  *Error conditions:*
423
 
424
+ - `resource_unavailable_try_again` — if some non-memory resource
425
+ limitation prevents initialization.
426
  - `operation_not_permitted` — if the thread does not have the privilege
427
  to perform the operation.
428
 
429
  ``` cpp
430
  ~condition_variable_any();
 
469
  - Atomically calls `lock.unlock()` and blocks on `*this`.
470
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock)
471
  and returns.
472
  - The function will unblock when signaled by a call to `notify_one()`, a
473
  call to `notify_all()`, or spuriously.
474
+
475
+ *Remarks:* If the function fails to meet the postcondition,
476
+ `std::terminate()` shall be called ([[except.terminate]]). This can
477
+ happen if the re-locking of the mutex throws an exception.
478
 
479
  `lock` is locked by the calling thread.
480
 
481
+ *Throws:* Nothing.
 
 
 
 
 
482
 
483
  ``` cpp
484
  template <class Lock, class Predicate>
485
  void wait(Lock& lock, Predicate pred);
486
  ```
487
 
488
+ *Effects:* Equivalent to:
489
 
490
  ``` cpp
491
  while (!pred())
492
  wait(lock);
493
  ```
 
505
  - The function will unblock when signaled by a call to `notify_one()`, a
506
  call to `notify_all()`, expiration of the absolute
507
  timeout ([[thread.req.timing]]) specified by `abs_time`, or
508
  spuriously.
509
  - If the function exits via an exception, `lock.lock()` shall be called
510
+ prior to exiting the function.
511
+
512
+ *Remarks:* If the function fails to meet the postcondition,
513
+ `std::terminate()` shall be called ([[except.terminate]]). This can
514
+ happen if the re-locking of the mutex throws an exception.
515
 
516
  `lock` is locked by the calling thread.
517
 
518
  *Returns:* `cv_status::timeout` if the absolute
519
  timeout ([[thread.req.timing]]) specified by `abs_time` expired,
520
  otherwise `cv_status::no_timeout`.
521
 
522
+ *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
 
 
 
 
 
523
 
524
  ``` cpp
525
  template <class Lock, class Rep, class Period>
526
  cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
527
  ```
528
 
529
+ *Effects:* Equivalent to:
530
 
531
  ``` cpp
532
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
533
  ```
534
 
535
  *Returns:* `cv_status::timeout` if the relative
536
  timeout ([[thread.req.timing]]) specified by `rel_time` expired,
537
  otherwise `cv_status::no_timeout`.
538
 
539
+ *Remarks:* If the function fails to meet the postcondition,
540
+ `std::terminate()` shall be called ([[except.terminate]]). This can
541
+ happen if the re-locking of the mutex throws an exception.
542
+
543
  `lock` is locked by the calling thread.
544
 
545
+ *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
 
 
 
 
 
546
 
547
  ``` cpp
548
  template <class Lock, class Clock, class Duration, class Predicate>
549
  bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
550
  ```
551
 
552
+ *Effects:* Equivalent to:
553
 
554
  ``` cpp
555
  while (!pred())
556
  if (wait_until(lock, abs_time) == cv_status::timeout)
557
  return pred();
558
  return true;
559
  ```
560
 
561
+ There is no blocking if `pred()` is initially `true`, or if the timeout
562
+ has already expired.
563
 
564
  The returned value indicates whether the predicate evaluates to `true`
565
  regardless of whether the timeout was triggered.
566
 
567
  ``` cpp
568
  template <class Lock, class Rep, class Period, class Predicate>
569
  bool wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred);
570
  ```
571
 
572
+ *Effects:* Equivalent to:
573
 
574
  ``` cpp
575
  return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));
576
  ```
577