From Jason Turner

[thread.condition]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpxrlb0i7j/{from.md → to.md} +191 -105
tmp/tmpxrlb0i7j/{from.md → to.md} RENAMED
@@ -2,35 +2,35 @@
2
 
3
  Condition variables provide synchronization primitives used to block a
4
  thread until notified by some other thread that some condition is met or
5
  until a system time is reached. Class `condition_variable` provides a
6
  condition variable that can only wait on an object of type
7
- `unique_lock<mutex>`, allowing maximum efficiency on some platforms.
8
  Class `condition_variable_any` provides a general condition variable
9
  that can wait on objects of user-supplied lock types.
10
 
11
  Condition variables permit concurrent invocation of the `wait`,
12
  `wait_for`, `wait_until`, `notify_one` and `notify_all` member
13
  functions.
14
 
15
- The execution of `notify_one` and `notify_all` shall be atomic. The
16
- execution of `wait`, `wait_for`, and `wait_until` shall be performed in
17
  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 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
- ### Header `<condition_variable>` synopsis <a id="condition_variable.syn">[[condition_variable.syn]]</a>
32
 
33
  ``` cpp
34
  namespace std {
35
  class condition_variable;
36
  class condition_variable_any;
@@ -45,22 +45,22 @@ namespace std {
45
 
46
  ``` cpp
47
  void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
48
  ```
49
 
50
- *Requires:* `lk` is locked by the calling thread and either
51
 
52
  - no other thread is waiting on `cond`, or
53
  - `lk.mutex()` returns the same value for each of the lock arguments
54
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
55
  `wait_until`) threads.
56
 
57
  *Effects:* Transfers ownership of the lock associated with `lk` into
58
  internal storage and schedules `cond` to be notified when the current
59
  thread exits, after all objects of thread storage duration associated
60
- with the current thread have been destroyed. This notification shall be
61
- as if:
62
 
63
  ``` cpp
64
  lk.unlock();
65
  cond.notify_all();
66
  ```
@@ -68,11 +68,11 @@ cond.notify_all();
68
  *Synchronization:* The implied `lk.unlock()` call is sequenced after the
69
  destruction of all objects with thread storage duration associated with
70
  the current thread.
71
 
72
  [*Note 1*: The supplied lock will be held until the thread exits, and
73
- care must be taken to ensure that this does not cause deadlock due to
74
  lock ordering issues. After calling `notify_all_at_thread_exit` it is
75
  recommended that the thread should be exited as soon as possible, and
76
  that no blocking or time-consuming tasks are run on that
77
  thread. — *end note*]
78
 
@@ -87,11 +87,10 @@ this lock is not released and reacquired prior to calling
87
 
88
  ``` cpp
89
  namespace std {
90
  class condition_variable {
91
  public:
92
-
93
  condition_variable();
94
  ~condition_variable();
95
 
96
  condition_variable(const condition_variable&) = delete;
97
  condition_variable& operator=(const condition_variable&) = delete;
@@ -106,60 +105,55 @@ namespace std {
106
  const chrono::time_point<Clock, Duration>& abs_time);
107
  template<class Clock, class Duration, class Predicate>
108
  bool wait_until(unique_lock<mutex>& lock,
109
  const chrono::time_point<Clock, Duration>& abs_time,
110
  Predicate pred);
111
-
112
  template<class Rep, class Period>
113
  cv_status wait_for(unique_lock<mutex>& lock,
114
  const chrono::duration<Rep, Period>& rel_time);
115
  template<class Rep, class Period, class Predicate>
116
  bool wait_for(unique_lock<mutex>& lock,
117
  const chrono::duration<Rep, Period>& rel_time,
118
  Predicate pred);
119
 
120
- using native_handle_type = implementation-defined; // See~[thread.req.native]
121
- native_handle_type native_handle(); // See~[thread.req.native]
122
  };
123
  }
124
  ```
125
 
126
- The class `condition_variable` shall be a standard-layout class (Clause 
127
- [[class]]).
128
 
129
  ``` cpp
130
  condition_variable();
131
  ```
132
 
133
- *Effects:* Constructs an object of type `condition_variable`.
134
-
135
  *Throws:* `system_error` when an exception is
136
- required ([[thread.req.exception]]).
137
 
138
  *Error conditions:*
139
 
140
  - `resource_unavailable_try_again` — if some non-memory resource
141
  limitation prevents initialization.
142
 
143
  ``` cpp
144
  ~condition_variable();
145
  ```
146
 
147
- *Requires:* There shall be no thread blocked on `*this`.
148
 
149
- [*Note 1*: That is, all threads shall have been notified; they may
150
  subsequently block on the lock specified in the wait. This relaxes the
151
  usual rules, which would have required all wait calls to happen before
152
- destruction. Only the notification to unblock the wait must happen
153
- before destruction. The user must take care to ensure that no threads
154
  wait on `*this` once the destructor has been started, especially when
155
  the waiting threads are calling the wait functions in a loop or using
156
  the overloads of `wait`, `wait_for`, or `wait_until` that take a
157
  predicate. — *end note*]
158
 
159
- *Effects:* Destroys the object.
160
-
161
  ``` cpp
162
  void notify_one() noexcept;
163
  ```
164
 
165
  *Effects:* If any threads are blocked waiting for `*this`, unblocks one
@@ -173,12 +167,12 @@ void notify_all() noexcept;
173
 
174
  ``` cpp
175
  void wait(unique_lock<mutex>& lock);
176
  ```
177
 
178
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
179
- the calling thread, and either
180
 
181
  - no other thread is waiting on this `condition_variable` object or
182
  - `lock.mutex()` returns the same value for each of the `lock` arguments
183
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
184
  `wait_until`) threads.
@@ -190,27 +184,27 @@ the calling thread, and either
190
  then returns.
191
  - The function will unblock when signaled by a call to `notify_one()` or
192
  a call to `notify_all()`, or spuriously.
193
 
194
  *Remarks:* If the function fails to meet the postcondition,
195
- `terminate()` shall be called ([[except.terminate]]).
196
 
197
  [*Note 2*: This can happen if the re-locking of the mutex throws an
198
  exception. — *end note*]
199
 
200
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
201
- locked by the calling thread.
202
 
203
  *Throws:* Nothing.
204
 
205
  ``` cpp
206
  template<class Predicate>
207
  void wait(unique_lock<mutex>& lock, Predicate pred);
208
  ```
209
 
210
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
211
- the calling thread, and either
212
 
213
  - no other thread is waiting on this `condition_variable` object or
214
  - `lock.mutex()` returns the same value for each of the `lock` arguments
215
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
216
  `wait_until`) threads.
@@ -221,28 +215,28 @@ the calling thread, and either
221
  while (!pred())
222
  wait(lock);
223
  ```
224
 
225
  *Remarks:* If the function fails to meet the postcondition,
226
- `terminate()` shall be called ([[except.terminate]]).
227
 
228
  [*Note 3*: This can happen if the re-locking of the mutex throws an
229
  exception. — *end note*]
230
 
231
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
232
- locked by the calling thread.
233
 
234
  *Throws:* Any exception thrown by `pred`.
235
 
236
  ``` cpp
237
  template<class Clock, class Duration>
238
  cv_status wait_until(unique_lock<mutex>& lock,
239
  const chrono::time_point<Clock, Duration>& abs_time);
240
  ```
241
 
242
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
243
- the calling thread, and either
244
 
245
  - no other thread is waiting on this `condition_variable` object or
246
  - `lock.mutex()` returns the same value for each of the `lock` arguments
247
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
248
  `wait_until`) threads.
@@ -252,38 +246,37 @@ the calling thread, and either
252
  - Atomically calls `lock.unlock()` and blocks on `*this`.
253
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock),
254
  then returns.
255
  - The function will unblock when signaled by a call to `notify_one()`, a
256
  call to `notify_all()`, expiration of the absolute
257
- timeout ([[thread.req.timing]]) specified by `abs_time`, or
258
- spuriously.
259
- - If the function exits via an exception, `lock.lock()` shall be called
260
- prior to exiting the function.
261
 
262
  *Remarks:* If the function fails to meet the postcondition,
263
- `terminate()` shall be called ([[except.terminate]]).
264
 
265
  [*Note 4*: This can happen if the re-locking of the mutex throws an
266
  exception. — *end note*]
267
 
268
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
269
- locked by the calling thread.
270
 
271
  *Returns:* `cv_status::timeout` if the absolute
272
- timeout ([[thread.req.timing]]) specified by `abs_time` expired,
273
- otherwise `cv_status::no_timeout`.
274
 
275
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
276
 
277
  ``` cpp
278
  template<class Rep, class Period>
279
  cv_status wait_for(unique_lock<mutex>& lock,
280
  const chrono::duration<Rep, Period>& rel_time);
281
  ```
282
 
283
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
284
- the calling thread, and either
285
 
286
  - no other thread is waiting on this `condition_variable` object or
287
  - `lock.mutex()` returns the same value for each of the `lock` arguments
288
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
289
  `wait_until`) threads.
@@ -293,33 +286,33 @@ the calling thread, and either
293
  ``` cpp
294
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
295
  ```
296
 
297
  *Returns:* `cv_status::timeout` if the relative
298
- timeout ([[thread.req.timing]]) specified by `rel_time` expired,
299
- otherwise `cv_status::no_timeout`.
300
 
301
  *Remarks:* If the function fails to meet the postcondition,
302
- `terminate()` shall be called ([[except.terminate]]).
303
 
304
  [*Note 5*: This can happen if the re-locking of the mutex throws an
305
  exception. — *end note*]
306
 
307
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
308
- locked by the calling thread.
309
 
310
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
311
 
312
  ``` cpp
313
  template<class Clock, class Duration, class Predicate>
314
  bool wait_until(unique_lock<mutex>& lock,
315
  const chrono::time_point<Clock, Duration>& abs_time,
316
  Predicate pred);
317
  ```
318
 
319
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
320
- the calling thread, and either
321
 
322
  - no other thread is waiting on this `condition_variable` object or
323
  - `lock.mutex()` returns the same value for each of the `lock` arguments
324
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
325
  `wait_until`) threads.
@@ -332,34 +325,34 @@ while (!pred())
332
  return pred();
333
  return true;
334
  ```
335
 
336
  *Remarks:* If the function fails to meet the postcondition,
337
- `terminate()` shall be called ([[except.terminate]]).
338
 
339
  [*Note 6*: This can happen if the re-locking of the mutex throws an
340
  exception. — *end note*]
341
 
342
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
343
- locked by the calling thread.
344
 
345
  [*Note 7*: The returned value indicates whether the predicate evaluated
346
  to `true` regardless of whether the timeout was
347
  triggered. — *end note*]
348
 
349
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]) or any
350
  exception thrown by `pred`.
351
 
352
  ``` cpp
353
  template<class Rep, class Period, class Predicate>
354
  bool wait_for(unique_lock<mutex>& lock,
355
  const chrono::duration<Rep, Period>& rel_time,
356
  Predicate pred);
357
  ```
358
 
359
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
360
- the calling thread, and either
361
 
362
  - no other thread is waiting on this `condition_variable` object or
363
  - `lock.mutex()` returns the same value for each of the `lock` arguments
364
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
365
  `wait_until`) threads.
@@ -372,34 +365,34 @@ return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred))
372
 
373
  [*Note 8*: There is no blocking if `pred()` is initially `true`, even
374
  if the timeout has already expired. — *end note*]
375
 
376
  *Remarks:* If the function fails to meet the postcondition,
377
- `terminate()` shall be called ([[except.terminate]]).
378
 
379
  [*Note 9*: This can happen if the re-locking of the mutex throws an
380
  exception. — *end note*]
381
 
382
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
383
- locked by the calling thread.
384
 
385
  [*Note 10*: The returned value indicates whether the predicate
386
  evaluates to `true` regardless of whether the timeout was
387
  triggered. — *end note*]
388
 
389
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]) or any
390
  exception thrown by `pred`.
391
 
392
  ### Class `condition_variable_any` <a id="thread.condition.condvarany">[[thread.condition.condvarany]]</a>
393
 
394
- A `Lock` type shall meet the `BasicLockable` requirements (
395
- [[thread.req.lockable.basic]]).
396
 
397
  [*Note 1*: All of the standard mutex types meet this requirement. If a
398
  `Lock` type other than one of the standard mutex types or a
399
  `unique_lock` wrapper for a standard mutex type is used with
400
- `condition_variable_any`, the user must ensure that any necessary
401
  synchronization is in place with respect to the predicate associated
402
  with the `condition_variable_any` instance. — *end note*]
403
 
404
  ``` cpp
405
  namespace std {
@@ -411,10 +404,12 @@ namespace std {
411
  condition_variable_any(const condition_variable_any&) = delete;
412
  condition_variable_any& operator=(const condition_variable_any&) = delete;
413
 
414
  void notify_one() noexcept;
415
  void notify_all() noexcept;
 
 
416
  template<class Lock>
417
  void wait(Lock& lock);
418
  template<class Lock, class Predicate>
419
  void wait(Lock& lock, Predicate pred);
420
 
@@ -424,24 +419,31 @@ namespace std {
424
  bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time,
425
  Predicate pred);
426
  template<class Lock, class Rep, class Period>
427
  cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
428
  template<class Lock, class Rep, class Period, class Predicate>
429
- bool wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time,
430
- Predicate pred);
 
 
 
 
 
 
 
 
 
431
  };
432
  }
433
  ```
434
 
435
  ``` cpp
436
  condition_variable_any();
437
  ```
438
 
439
- *Effects:* Constructs an object of type `condition_variable_any`.
440
-
441
  *Throws:* `bad_alloc` or `system_error` when an exception is
442
- required ([[thread.req.exception]]).
443
 
444
  *Error conditions:*
445
 
446
  - `resource_unavailable_try_again` — if some non-memory resource
447
  limitation prevents initialization.
@@ -450,24 +452,22 @@ required ([[thread.req.exception]]).
450
 
451
  ``` cpp
452
  ~condition_variable_any();
453
  ```
454
 
455
- *Requires:* There shall be no thread blocked on `*this`.
456
 
457
- [*Note 1*: That is, all threads shall have been notified; they may
458
  subsequently block on the lock specified in the wait. This relaxes the
459
  usual rules, which would have required all wait calls to happen before
460
- destruction. Only the notification to unblock the wait must happen
461
- before destruction. The user must take care to ensure that no threads
462
  wait on `*this` once the destructor has been started, especially when
463
  the waiting threads are calling the wait functions in a loop or using
464
  the overloads of `wait`, `wait_for`, or `wait_until` that take a
465
  predicate. — *end note*]
466
 
467
- *Effects:* Destroys the object.
468
-
469
  ``` cpp
470
  void notify_one() noexcept;
471
  ```
472
 
473
  *Effects:* If any threads are blocked waiting for `*this`, unblocks one
@@ -477,34 +477,32 @@ of those threads.
477
  void notify_all() noexcept;
478
  ```
479
 
480
  *Effects:* Unblocks all threads that are blocked waiting for `*this`.
481
 
 
 
482
  ``` cpp
483
  template<class Lock>
484
  void wait(Lock& lock);
485
  ```
486
 
487
- [*Note 2*: If any of the `wait` functions exits via an exception, it is
488
- unspecified whether the `Lock` is held. One can use a `Lock` type that
489
- allows to query that, such as the `unique_lock` wrapper. — *end note*]
490
-
491
  *Effects:*
492
 
493
  - Atomically calls `lock.unlock()` and blocks on `*this`.
494
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock)
495
  and returns.
496
  - The function will unblock when signaled by a call to `notify_one()`, a
497
  call to `notify_all()`, or spuriously.
498
 
499
  *Remarks:* If the function fails to meet the postcondition,
500
- `terminate()` shall be called ([[except.terminate]]).
501
 
502
- [*Note 3*: This can happen if the re-locking of the mutex throws an
503
  exception. — *end note*]
504
 
505
- *Postconditions:* `lock` is locked by the calling thread.
506
 
507
  *Throws:* Nothing.
508
 
509
  ``` cpp
510
  template<class Lock, class Predicate>
@@ -528,28 +526,27 @@ template <class Lock, class Clock, class Duration>
528
  - Atomically calls `lock.unlock()` and blocks on `*this`.
529
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock)
530
  and returns.
531
  - The function will unblock when signaled by a call to `notify_one()`, a
532
  call to `notify_all()`, expiration of the absolute
533
- timeout ([[thread.req.timing]]) specified by `abs_time`, or
534
- spuriously.
535
- - If the function exits via an exception, `lock.lock()` shall be called
536
- prior to exiting the function.
537
 
538
  *Remarks:* If the function fails to meet the postcondition,
539
- `terminate()` shall be called ([[except.terminate]]).
540
 
541
- [*Note 4*: This can happen if the re-locking of the mutex throws an
542
  exception. — *end note*]
543
 
544
- *Postconditions:* `lock` is locked by the calling thread.
545
 
546
  *Returns:* `cv_status::timeout` if the absolute
547
- timeout ([[thread.req.timing]]) specified by `abs_time` expired,
548
- otherwise `cv_status::no_timeout`.
549
 
550
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
551
 
552
  ``` cpp
553
  template<class Lock, class Rep, class Period>
554
  cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
555
  ```
@@ -559,22 +556,22 @@ template <class Lock, class Rep, class Period>
559
  ``` cpp
560
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
561
  ```
562
 
563
  *Returns:* `cv_status::timeout` if the relative
564
- timeout ([[thread.req.timing]]) specified by `rel_time` expired,
565
- otherwise `cv_status::no_timeout`.
566
 
567
  *Remarks:* If the function fails to meet the postcondition,
568
- `terminate()` shall be called ([[except.terminate]]).
569
 
570
- [*Note 5*: This can happen if the re-locking of the mutex throws an
571
  exception. — *end note*]
572
 
573
- *Postconditions:* `lock` is locked by the calling thread.
574
 
575
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
576
 
577
  ``` cpp
578
  template<class Lock, class Clock, class Duration, class Predicate>
579
  bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
580
  ```
@@ -586,14 +583,14 @@ while (!pred())
586
  if (wait_until(lock, abs_time) == cv_status::timeout)
587
  return pred();
588
  return true;
589
  ```
590
 
591
- [*Note 6*: There is no blocking if `pred()` is initially `true`, or if
592
  the timeout has already expired. — *end note*]
593
 
594
- [*Note 7*: The returned value indicates whether the predicate evaluates
595
  to `true` regardless of whether the timeout was
596
  triggered. — *end note*]
597
 
598
  ``` cpp
599
  template<class Lock, class Rep, class Period, class Predicate>
@@ -604,5 +601,94 @@ template <class Lock, class Rep, class Period, class Predicate>
604
 
605
  ``` cpp
606
  return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));
607
  ```
608
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  Condition variables provide synchronization primitives used to block a
4
  thread until notified by some other thread that some condition is met or
5
  until a system time is reached. Class `condition_variable` provides a
6
  condition variable that can only wait on an object of type
7
+ `unique_lock<mutex>`, allowing the implementation to be more efficient.
8
  Class `condition_variable_any` provides a general condition variable
9
  that can wait on objects of user-supplied lock types.
10
 
11
  Condition variables permit concurrent invocation of the `wait`,
12
  `wait_for`, `wait_until`, `notify_one` and `notify_all` member
13
  functions.
14
 
15
+ The executions of `notify_one` and `notify_all` are atomic. The
16
+ executions of `wait`, `wait_for`, and `wait_until` are performed in
17
  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 behaves 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
+ ### Header `<condition_variable>` synopsis <a id="condition.variable.syn">[[condition.variable.syn]]</a>
32
 
33
  ``` cpp
34
  namespace std {
35
  class condition_variable;
36
  class condition_variable_any;
 
45
 
46
  ``` cpp
47
  void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
48
  ```
49
 
50
+ *Preconditions:* `lk` is locked by the calling thread and either
51
 
52
  - no other thread is waiting on `cond`, or
53
  - `lk.mutex()` returns the same value for each of the lock arguments
54
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
55
  `wait_until`) threads.
56
 
57
  *Effects:* Transfers ownership of the lock associated with `lk` into
58
  internal storage and schedules `cond` to be notified when the current
59
  thread exits, after all objects of thread storage duration associated
60
+ with the current thread have been destroyed. This notification is
61
+ equivalent to:
62
 
63
  ``` cpp
64
  lk.unlock();
65
  cond.notify_all();
66
  ```
 
68
  *Synchronization:* The implied `lk.unlock()` call is sequenced after the
69
  destruction of all objects with thread storage duration associated with
70
  the current thread.
71
 
72
  [*Note 1*: The supplied lock will be held until the thread exits, and
73
+ care should be taken to ensure that this does not cause deadlock due to
74
  lock ordering issues. After calling `notify_all_at_thread_exit` it is
75
  recommended that the thread should be exited as soon as possible, and
76
  that no blocking or time-consuming tasks are run on that
77
  thread. — *end note*]
78
 
 
87
 
88
  ``` cpp
89
  namespace std {
90
  class condition_variable {
91
  public:
 
92
  condition_variable();
93
  ~condition_variable();
94
 
95
  condition_variable(const condition_variable&) = delete;
96
  condition_variable& operator=(const condition_variable&) = delete;
 
105
  const chrono::time_point<Clock, Duration>& abs_time);
106
  template<class Clock, class Duration, class Predicate>
107
  bool wait_until(unique_lock<mutex>& lock,
108
  const chrono::time_point<Clock, Duration>& abs_time,
109
  Predicate pred);
 
110
  template<class Rep, class Period>
111
  cv_status wait_for(unique_lock<mutex>& lock,
112
  const chrono::duration<Rep, Period>& rel_time);
113
  template<class Rep, class Period, class Predicate>
114
  bool wait_for(unique_lock<mutex>& lock,
115
  const chrono::duration<Rep, Period>& rel_time,
116
  Predicate pred);
117
 
118
+ using native_handle_type = implementation-defined; // see~[thread.req.native]
119
+ native_handle_type native_handle(); // see~[thread.req.native]
120
  };
121
  }
122
  ```
123
 
124
+ The class `condition_variable` is a standard-layout class
125
+ [[class.prop]].
126
 
127
  ``` cpp
128
  condition_variable();
129
  ```
130
 
 
 
131
  *Throws:* `system_error` when an exception is
132
+ required [[thread.req.exception]].
133
 
134
  *Error conditions:*
135
 
136
  - `resource_unavailable_try_again` — if some non-memory resource
137
  limitation prevents initialization.
138
 
139
  ``` cpp
140
  ~condition_variable();
141
  ```
142
 
143
+ *Preconditions:* There is no thread blocked on `*this`.
144
 
145
+ [*Note 1*: That is, all threads have been notified; they could
146
  subsequently block on the lock specified in the wait. This relaxes the
147
  usual rules, which would have required all wait calls to happen before
148
+ destruction. Only the notification to unblock the wait needs to happen
149
+ before destruction. The user should take care to ensure that no threads
150
  wait on `*this` once the destructor has been started, especially when
151
  the waiting threads are calling the wait functions in a loop or using
152
  the overloads of `wait`, `wait_for`, or `wait_until` that take a
153
  predicate. — *end note*]
154
 
 
 
155
  ``` cpp
156
  void notify_one() noexcept;
157
  ```
158
 
159
  *Effects:* If any threads are blocked waiting for `*this`, unblocks one
 
167
 
168
  ``` cpp
169
  void wait(unique_lock<mutex>& lock);
170
  ```
171
 
172
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
173
+ locked by the calling thread, and either
174
 
175
  - no other thread is waiting on this `condition_variable` object or
176
  - `lock.mutex()` returns the same value for each of the `lock` arguments
177
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
178
  `wait_until`) threads.
 
184
  then returns.
185
  - The function will unblock when signaled by a call to `notify_one()` or
186
  a call to `notify_all()`, or spuriously.
187
 
188
  *Remarks:* If the function fails to meet the postcondition,
189
+ `terminate()` is called [[except.terminate]].
190
 
191
  [*Note 2*: This can happen if the re-locking of the mutex throws an
192
  exception. — *end note*]
193
 
194
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
195
+ the calling thread.
196
 
197
  *Throws:* Nothing.
198
 
199
  ``` cpp
200
  template<class Predicate>
201
  void wait(unique_lock<mutex>& lock, Predicate pred);
202
  ```
203
 
204
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
205
+ locked by 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`, `wait_for`, or
210
  `wait_until`) threads.
 
215
  while (!pred())
216
  wait(lock);
217
  ```
218
 
219
  *Remarks:* If the function fails to meet the postcondition,
220
+ `terminate()` is called [[except.terminate]].
221
 
222
  [*Note 3*: This can happen if the re-locking of the mutex throws an
223
  exception. — *end note*]
224
 
225
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
226
+ the calling thread.
227
 
228
  *Throws:* Any exception thrown by `pred`.
229
 
230
  ``` cpp
231
  template<class Clock, class Duration>
232
  cv_status wait_until(unique_lock<mutex>& lock,
233
  const chrono::time_point<Clock, Duration>& abs_time);
234
  ```
235
 
236
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
237
+ locked by the calling thread, and either
238
 
239
  - no other thread is waiting on this `condition_variable` object or
240
  - `lock.mutex()` returns the same value for each of the `lock` arguments
241
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
242
  `wait_until`) threads.
 
246
  - Atomically calls `lock.unlock()` and blocks on `*this`.
247
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock),
248
  then returns.
249
  - The function will unblock when signaled by a call to `notify_one()`, a
250
  call to `notify_all()`, expiration of the absolute
251
+ timeout [[thread.req.timing]] specified by `abs_time`, or spuriously.
252
+ - If the function exits via an exception, `lock.lock()` is called prior
253
+ to exiting the function.
 
254
 
255
  *Remarks:* If the function fails to meet the postcondition,
256
+ `terminate()` is called [[except.terminate]].
257
 
258
  [*Note 4*: This can happen if the re-locking of the mutex throws an
259
  exception. — *end note*]
260
 
261
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
262
+ the calling thread.
263
 
264
  *Returns:* `cv_status::timeout` if the absolute
265
+ timeout [[thread.req.timing]] specified by `abs_time` expired, otherwise
266
+ `cv_status::no_timeout`.
267
 
268
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
269
 
270
  ``` cpp
271
  template<class Rep, class Period>
272
  cv_status wait_for(unique_lock<mutex>& lock,
273
  const chrono::duration<Rep, Period>& rel_time);
274
  ```
275
 
276
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
277
+ locked by the calling thread, and either
278
 
279
  - no other thread is waiting on this `condition_variable` object or
280
  - `lock.mutex()` returns the same value for each of the `lock` arguments
281
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
282
  `wait_until`) threads.
 
286
  ``` cpp
287
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
288
  ```
289
 
290
  *Returns:* `cv_status::timeout` if the relative
291
+ timeout [[thread.req.timing]] specified by `rel_time` expired, otherwise
292
+ `cv_status::no_timeout`.
293
 
294
  *Remarks:* If the function fails to meet the postcondition,
295
+ `terminate()` is called [[except.terminate]].
296
 
297
  [*Note 5*: This can happen if the re-locking of the mutex throws an
298
  exception. — *end note*]
299
 
300
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
301
+ the calling thread.
302
 
303
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
304
 
305
  ``` cpp
306
  template<class Clock, class Duration, class Predicate>
307
  bool wait_until(unique_lock<mutex>& lock,
308
  const chrono::time_point<Clock, Duration>& abs_time,
309
  Predicate pred);
310
  ```
311
 
312
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
313
+ locked by the calling thread, and either
314
 
315
  - no other thread is waiting on this `condition_variable` object or
316
  - `lock.mutex()` returns the same value for each of the `lock` arguments
317
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
318
  `wait_until`) threads.
 
325
  return pred();
326
  return true;
327
  ```
328
 
329
  *Remarks:* If the function fails to meet the postcondition,
330
+ `terminate()` is called [[except.terminate]].
331
 
332
  [*Note 6*: This can happen if the re-locking of the mutex throws an
333
  exception. — *end note*]
334
 
335
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
336
+ the calling thread.
337
 
338
  [*Note 7*: The returned value indicates whether the predicate evaluated
339
  to `true` regardless of whether the timeout was
340
  triggered. — *end note*]
341
 
342
+ *Throws:* Timeout-related exceptions [[thread.req.timing]] or any
343
  exception thrown by `pred`.
344
 
345
  ``` cpp
346
  template<class Rep, class Period, class Predicate>
347
  bool wait_for(unique_lock<mutex>& lock,
348
  const chrono::duration<Rep, Period>& rel_time,
349
  Predicate pred);
350
  ```
351
 
352
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
353
+ locked by the calling thread, and either
354
 
355
  - no other thread is waiting on this `condition_variable` object or
356
  - `lock.mutex()` returns the same value for each of the `lock` arguments
357
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
358
  `wait_until`) threads.
 
365
 
366
  [*Note 8*: There is no blocking if `pred()` is initially `true`, even
367
  if the timeout has already expired. — *end note*]
368
 
369
  *Remarks:* If the function fails to meet the postcondition,
370
+ `terminate()` is called [[except.terminate]].
371
 
372
  [*Note 9*: This can happen if the re-locking of the mutex throws an
373
  exception. — *end note*]
374
 
375
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
376
+ the calling thread.
377
 
378
  [*Note 10*: The returned value indicates whether the predicate
379
  evaluates to `true` regardless of whether the timeout was
380
  triggered. — *end note*]
381
 
382
+ *Throws:* Timeout-related exceptions [[thread.req.timing]] or any
383
  exception thrown by `pred`.
384
 
385
  ### Class `condition_variable_any` <a id="thread.condition.condvarany">[[thread.condition.condvarany]]</a>
386
 
387
+ A `Lock` type shall meet the *Cpp17BasicLockable* requirements
388
+ [[thread.req.lockable.basic]].
389
 
390
  [*Note 1*: All of the standard mutex types meet this requirement. If a
391
  `Lock` type other than one of the standard mutex types or a
392
  `unique_lock` wrapper for a standard mutex type is used with
393
+ `condition_variable_any`, the user should ensure that any necessary
394
  synchronization is in place with respect to the predicate associated
395
  with the `condition_variable_any` instance. — *end note*]
396
 
397
  ``` cpp
398
  namespace std {
 
404
  condition_variable_any(const condition_variable_any&) = delete;
405
  condition_variable_any& operator=(const condition_variable_any&) = delete;
406
 
407
  void notify_one() noexcept;
408
  void notify_all() noexcept;
409
+
410
+ // [thread.condvarany.wait], noninterruptible waits
411
  template<class Lock>
412
  void wait(Lock& lock);
413
  template<class Lock, class Predicate>
414
  void wait(Lock& lock, Predicate pred);
415
 
 
419
  bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time,
420
  Predicate pred);
421
  template<class Lock, class Rep, class Period>
422
  cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
423
  template<class Lock, class Rep, class Period, class Predicate>
424
+ bool wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred);
425
+
426
+ // [thread.condvarany.intwait], interruptible waits
427
+ template<class Lock, class Predicate>
428
+ bool wait(Lock& lock, stop_token stoken, Predicate pred);
429
+ template<class Lock, class Clock, class Duration, class Predicate>
430
+ bool wait_until(Lock& lock, stop_token stoken,
431
+ const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
432
+ template<class Lock, class Rep, class Period, class Predicate>
433
+ bool wait_for(Lock& lock, stop_token stoken,
434
+ const chrono::duration<Rep, Period>& rel_time, Predicate pred);
435
  };
436
  }
437
  ```
438
 
439
  ``` cpp
440
  condition_variable_any();
441
  ```
442
 
 
 
443
  *Throws:* `bad_alloc` or `system_error` when an exception is
444
+ required [[thread.req.exception]].
445
 
446
  *Error conditions:*
447
 
448
  - `resource_unavailable_try_again` — if some non-memory resource
449
  limitation prevents initialization.
 
452
 
453
  ``` cpp
454
  ~condition_variable_any();
455
  ```
456
 
457
+ *Preconditions:* There is no thread blocked on `*this`.
458
 
459
+ [*Note 1*: That is, all threads have been notified; they could
460
  subsequently block on the lock specified in the wait. This relaxes the
461
  usual rules, which would have required all wait calls to happen before
462
+ destruction. Only the notification to unblock the wait needs to happen
463
+ before destruction. The user should take care to ensure that no threads
464
  wait on `*this` once the destructor has been started, especially when
465
  the waiting threads are calling the wait functions in a loop or using
466
  the overloads of `wait`, `wait_for`, or `wait_until` that take a
467
  predicate. — *end note*]
468
 
 
 
469
  ``` cpp
470
  void notify_one() noexcept;
471
  ```
472
 
473
  *Effects:* If any threads are blocked waiting for `*this`, unblocks one
 
477
  void notify_all() noexcept;
478
  ```
479
 
480
  *Effects:* Unblocks all threads that are blocked waiting for `*this`.
481
 
482
+ #### Noninterruptible waits <a id="thread.condvarany.wait">[[thread.condvarany.wait]]</a>
483
+
484
  ``` cpp
485
  template<class Lock>
486
  void wait(Lock& lock);
487
  ```
488
 
 
 
 
 
489
  *Effects:*
490
 
491
  - Atomically calls `lock.unlock()` and blocks on `*this`.
492
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock)
493
  and returns.
494
  - The function will unblock when signaled by a call to `notify_one()`, a
495
  call to `notify_all()`, or spuriously.
496
 
497
  *Remarks:* If the function fails to meet the postcondition,
498
+ `terminate()` is called [[except.terminate]].
499
 
500
+ [*Note 1*: This can happen if the re-locking of the mutex throws an
501
  exception. — *end note*]
502
 
503
+ *Ensures:* `lock` is locked by the calling thread.
504
 
505
  *Throws:* Nothing.
506
 
507
  ``` cpp
508
  template<class Lock, class Predicate>
 
526
  - Atomically calls `lock.unlock()` and blocks on `*this`.
527
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock)
528
  and returns.
529
  - The function will unblock when signaled by a call to `notify_one()`, a
530
  call to `notify_all()`, expiration of the absolute
531
+ timeout [[thread.req.timing]] specified by `abs_time`, or spuriously.
532
+ - If the function exits via an exception, `lock.lock()` is called prior
533
+ to exiting the function.
 
534
 
535
  *Remarks:* If the function fails to meet the postcondition,
536
+ `terminate()` is called [[except.terminate]].
537
 
538
+ [*Note 2*: This can happen if the re-locking of the mutex throws an
539
  exception. — *end note*]
540
 
541
+ *Ensures:* `lock` is locked by the calling thread.
542
 
543
  *Returns:* `cv_status::timeout` if the absolute
544
+ timeout [[thread.req.timing]] specified by `abs_time` expired, otherwise
545
+ `cv_status::no_timeout`.
546
 
547
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
548
 
549
  ``` cpp
550
  template<class Lock, class Rep, class Period>
551
  cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
552
  ```
 
556
  ``` cpp
557
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
558
  ```
559
 
560
  *Returns:* `cv_status::timeout` if the relative
561
+ timeout [[thread.req.timing]] specified by `rel_time` expired, otherwise
562
+ `cv_status::no_timeout`.
563
 
564
  *Remarks:* If the function fails to meet the postcondition,
565
+ `terminate()` is called [[except.terminate]].
566
 
567
+ [*Note 3*: This can happen if the re-locking of the mutex throws an
568
  exception. — *end note*]
569
 
570
+ *Ensures:* `lock` is locked by the calling thread.
571
 
572
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
573
 
574
  ``` cpp
575
  template<class Lock, class Clock, class Duration, class Predicate>
576
  bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
577
  ```
 
583
  if (wait_until(lock, abs_time) == cv_status::timeout)
584
  return pred();
585
  return true;
586
  ```
587
 
588
+ [*Note 4*: There is no blocking if `pred()` is initially `true`, or if
589
  the timeout has already expired. — *end note*]
590
 
591
+ [*Note 5*: The returned value indicates whether the predicate evaluates
592
  to `true` regardless of whether the timeout was
593
  triggered. — *end note*]
594
 
595
  ``` cpp
596
  template<class Lock, class Rep, class Period, class Predicate>
 
601
 
602
  ``` cpp
603
  return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));
604
  ```
605
 
606
+ #### Interruptible waits <a id="thread.condvarany.intwait">[[thread.condvarany.intwait]]</a>
607
+
608
+ The following wait functions will be notified when there is a stop
609
+ request on the passed `stop_token`. In that case the functions return
610
+ immediately, returning `false` if the predicate evaluates to `false`.
611
+
612
+ ``` cpp
613
+ template<class Lock, class Predicate>
614
+ bool wait(Lock& lock, stop_token stoken, Predicate pred);
615
+ ```
616
+
617
+ *Effects:* Registers for the duration of this call `*this` to get
618
+ notified on a stop request on `stoken` during this call and then
619
+ equivalent to:
620
+
621
+ ``` cpp
622
+ while (!stoken.stop_requested()) {
623
+ if (pred())
624
+ return true;
625
+ wait(lock);
626
+ }
627
+ return pred();
628
+ ```
629
+
630
+ [*Note 1*: The returned value indicates whether the predicate evaluated
631
+ to `true` regardless of whether there was a stop request. — *end note*]
632
+
633
+ *Ensures:* `lock` is locked by the calling thread.
634
+
635
+ *Remarks:* If the function fails to meet the postcondition, `terminate`
636
+ is called [[except.terminate]].
637
+
638
+ [*Note 2*: This can happen if the re-locking of the mutex throws an
639
+ exception. — *end note*]
640
+
641
+ *Throws:* Any exception thrown by `pred`.
642
+
643
+ ``` cpp
644
+ template<class Lock, class Clock, class Duration, class Predicate>
645
+ bool wait_until(Lock& lock, stop_token stoken,
646
+ const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
647
+ ```
648
+
649
+ *Effects:* Registers for the duration of this call `*this` to get
650
+ notified on a stop request on `stoken` during this call and then
651
+ equivalent to:
652
+
653
+ ``` cpp
654
+ while (!stoken.stop_requested()) {
655
+ if (pred())
656
+ return true;
657
+ if (cv.wait_until(lock, abs_time) == cv_status::timeout)
658
+ return pred();
659
+ }
660
+ return pred();
661
+ ```
662
+
663
+ [*Note 3*: There is no blocking if `pred()` is initially `true`,
664
+ `stoken.stop_requested()` was already `true` or the timeout has already
665
+ expired. — *end note*]
666
+
667
+ [*Note 4*: The returned value indicates whether the predicate evaluated
668
+ to `true` regardless of whether the timeout was triggered or a stop
669
+ request was made. — *end note*]
670
+
671
+ *Ensures:* `lock` is locked by the calling thread.
672
+
673
+ *Remarks:* If the function fails to meet the postcondition, `terminate`
674
+ is called [[except.terminate]].
675
+
676
+ [*Note 5*: This can happen if the re-locking of the mutex throws an
677
+ exception. — *end note*]
678
+
679
+ *Throws:* Timeout-related exceptions [[thread.req.timing]], or any
680
+ exception thrown by `pred`.
681
+
682
+ ``` cpp
683
+ template<class Lock, class Rep, class Period, class Predicate>
684
+ bool wait_for(Lock& lock, stop_token stoken,
685
+ const chrono::duration<Rep, Period>& rel_time, Predicate pred);
686
+ ```
687
+
688
+ *Effects:* Equivalent to:
689
+
690
+ ``` cpp
691
+ return wait_until(lock, std::move(stoken), chrono::steady_clock::now() + rel_time,
692
+ std::move(pred));
693
+ ```
694
+