From Jason Turner

[thread]

Large diff (207.3 KB) - rendering may be slow on some devices

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpw8u_m7oa/{from.md → to.md} +2102 -878
tmp/tmpw8u_m7oa/{from.md → to.md} RENAMED
@@ -1,58 +1,62 @@
1
  # Thread support library <a id="thread">[[thread]]</a>
2
 
3
  ## General <a id="thread.general">[[thread.general]]</a>
4
 
5
  The following subclauses describe components to create and manage
6
- threads ([[intro.multithread]]), perform mutual exclusion, and
7
- communicate conditions and values between threads, as summarized in
8
- Table  [[tab:thread.lib.summary]].
9
 
10
- **Table: Thread support library summary** <a id="tab:thread.lib.summary">[tab:thread.lib.summary]</a>
11
 
12
  | Subclause | | Header |
13
- | -------------------- | ------------------- | ---------------------- |
14
  | [[thread.req]] | Requirements | |
 
15
  | [[thread.threads]] | Threads | `<thread>` |
16
- | [[thread.mutex]] | Mutual exclusion | `<mutex>` |
17
- | | | `<shared_mutex>` |
18
  | [[thread.condition]] | Condition variables | `<condition_variable>` |
 
 
19
  | [[futures]] | Futures | `<future>` |
20
 
21
 
22
  ## Requirements <a id="thread.req">[[thread.req]]</a>
23
 
24
  ### Template parameter names <a id="thread.req.paramname">[[thread.req.paramname]]</a>
25
 
26
  Throughout this Clause, the names of template parameters are used to
27
  express type requirements. If a template parameter is named `Predicate`,
28
  `operator()` applied to the template argument shall return a value that
29
- is convertible to `bool`.
 
 
30
 
31
  ### Exceptions <a id="thread.req.exception">[[thread.req.exception]]</a>
32
 
33
  Some functions described in this Clause are specified to throw
34
- exceptions of type `system_error` ([[syserr.syserr]]). Such exceptions
35
- shall be thrown if any of the function’s error conditions is detected or
36
- a call to an operating system or other underlying API results in an
37
- error that prevents the library function from meeting its
38
- specifications. Failure to allocate storage shall be reported as
39
- described in  [[res.on.exception.handling]].
40
 
41
  [*Example 1*: Consider a function in this clause that is specified to
42
  throw exceptions of type `system_error` and specifies error conditions
43
  that include `operation_not_permitted` for a thread that does not have
44
  the privilege to perform the operation. Assume that, during the
45
  execution of this function, an `errno` of `EPERM` is reported by a POSIX
46
  API call used by the implementation. Since POSIX specifies an `errno` of
47
  `EPERM` when “the caller does not have the privilege to perform the
48
  operation”, the implementation maps `EPERM` to an `error_condition` of
49
- `operation_not_permitted` ([[syserr]]) and an exception of type
50
  `system_error` is thrown. — *end example*]
51
 
52
  The `error_code` reported by such an exception’s `code()` member
53
- function shall compare equal to one of the conditions specified in the
54
  function’s error condition element.
55
 
56
  ### Native handles <a id="thread.req.native">[[thread.req.native]]</a>
57
 
58
  Several classes described in this Clause have members
@@ -76,98 +80,98 @@ induces a “quality of implementation” delay, expressed as duration Dᵢ.
76
  Ideally, this delay would be zero. Further, any contention for processor
77
  and memory resources induces a “quality of management” delay, expressed
78
  as duration Dₘ. The delay durations may vary from timeout to timeout,
79
  but in all cases shorter is better.
80
 
81
- The member functions whose names end in `_for` take an argument that
82
- specifies a duration. These functions produce relative timeouts.
83
- Implementations should use a steady clock to measure time for these
84
- functions.[^1] Given a duration argument Dₜ, the real-time duration of
85
- the timeout is Dₜ + Dᵢ + Dₘ.
86
 
87
- The member functions whose names end in `_until` take an argument that
88
  specifies a time point. These functions produce absolute timeouts.
89
  Implementations should use the clock specified in the time point to
90
  measure time for these functions. Given a clock time point argument Cₜ,
91
  the clock time point of the return from timeout should be Cₜ + Dᵢ + Dₘ
92
  when the clock is not adjusted during the timeout. If the clock is
93
  adjusted to the time Cₐ during the timeout, the behavior should be as
94
  follows:
95
 
96
- - if Cₐ > Cₜ, the waiting function should wake as soon as possible, i.e.
97
- Cₐ + Dᵢ + Dₘ, since the timeout is already satisfied. \[*Note 1*: This
98
  specification may result in the total duration of the wait decreasing
99
- when measured against a steady clock. — *end note*]
100
- - if Cₐ <= Cₜ, the waiting function should not time out until
101
- `Clock::now()` returns a time Cₙ >= Cₜ, i.e. waking at Cₜ + Dᵢ + Dₘ.
102
- \[*Note 2*: When the clock is adjusted backwards, this specification
103
- may result in the total duration of the wait increasing when measured
104
  against a steady clock. When the clock is adjusted forwards, this
105
- specification may result in the total duration of the wait decreasing
106
  when measured against a steady clock. — *end note*]
107
 
108
- An implementation shall return from such a timeout at any point from the
109
- time specified above to the time it would return from a steady-clock
110
- relative timeout on the difference between Cₜ and the time point of the
111
- call to the `_until` function.
112
 
113
- [*Note 3*: Implementations should decrease the duration of the wait
114
  when the clock is adjusted forwards. — *end note*]
115
 
116
- [*Note 4*: If the clock is not synchronized with a steady clock, e.g.,
117
  a CPU time clock, these timeouts might not provide useful
118
  functionality. — *end note*]
119
 
120
  The resolution of timing provided by an implementation depends on both
121
  operating system and hardware. The finest resolution provided by an
122
  implementation is called the *native resolution*.
123
 
124
- Implementation-provided clocks that are used for these functions shall
125
- meet the `TrivialClock` requirements ([[time.clock.req]]).
126
 
127
  A function that takes an argument which specifies a timeout will throw
128
  if, during its execution, a clock, time point, or time duration throws
129
  an exception. Such exceptions are referred to as *timeout-related
130
  exceptions*.
131
 
132
- [*Note 5*: Instantiations of clock, time point and duration types
133
  supplied by the implementation as specified in  [[time.clock]] do not
134
  throw exceptions. — *end note*]
135
 
136
- ### Requirements for `Lockable` types <a id="thread.req.lockable">[[thread.req.lockable]]</a>
137
 
138
  #### In general <a id="thread.req.lockable.general">[[thread.req.lockable.general]]</a>
139
 
140
  An *execution agent* is an entity such as a thread that may perform work
141
  in parallel with other execution agents.
142
 
143
- [*Note 1*: Implementations or users may introduce other kinds of agents
144
  such as processes or thread-pool tasks. — *end note*]
145
 
146
- The calling agent is determined by context, e.g. the calling thread that
147
- contains the call, and so on.
148
 
149
  [*Note 2*: Some lockable objects are “agent oblivious” in that they
150
  work for any execution agent model because they do not determine or
151
  store the agent’s ID (e.g., an ordinary spin lock). — *end note*]
152
 
153
- The standard library templates `unique_lock` ([[thread.lock.unique]]),
154
- `shared_lock` ([[thread.lock.shared]]), `scoped_lock` (
155
- [[thread.lock.scoped]]), `lock_guard` ([[thread.lock.guard]]), `lock`,
156
- `try_lock` ([[thread.lock.algorithm]]), and `condition_variable_any` (
157
- [[thread.condition.condvarany]]) all operate on user-supplied lockable
158
- objects. The `BasicLockable` requirements, the `Lockable` requirements,
159
- and the `TimedLockable` requirements list the requirements imposed by
160
- these library types in order to acquire or release ownership of a `lock`
161
- by a given execution agent.
162
 
163
  [*Note 3*: The nature of any lock ownership and any synchronization it
164
- may entail are not part of these requirements. — *end note*]
165
 
166
- #### `BasicLockable` requirements <a id="thread.req.lockable.basic">[[thread.req.lockable.basic]]</a>
167
 
168
- A type `L` meets the `BasicLockable` requirements if the following
169
  expressions are well-formed and have the specified semantics (`m`
170
  denotes a value of type `L`).
171
 
172
  ``` cpp
173
  m.lock()
@@ -179,20 +183,20 @@ acquired for the current execution agent.
179
 
180
  ``` cpp
181
  m.unlock()
182
  ```
183
 
184
- *Requires:* The current execution agent shall hold a lock on `m`.
185
 
186
  *Effects:* Releases a lock on `m` held by the current execution agent.
187
 
188
  *Throws:* Nothing.
189
 
190
- #### `Lockable` requirements <a id="thread.req.lockable.req">[[thread.req.lockable.req]]</a>
191
 
192
- A type `L` meets the `Lockable` requirements if it meets the
193
- `BasicLockable` requirements and the following expressions are
194
  well-formed and have the specified semantics (`m` denotes a value of
195
  type `L`).
196
 
197
  ``` cpp
198
  m.try_lock()
@@ -204,60 +208,490 @@ been acquired for the current execution agent.
204
 
205
  *Return type:* `bool`.
206
 
207
  *Returns:* `true` if the lock was acquired, `false` otherwise.
208
 
209
- #### `TimedLockable` requirements <a id="thread.req.lockable.timed">[[thread.req.lockable.timed]]</a>
210
 
211
- A type `L` meets the `TimedLockable` requirements if it meets the
212
- `Lockable` requirements and the following expressions are well-formed
213
- and have the specified semantics (`m` denotes a value of type `L`,
214
- `rel_time` denotes a value of an instantiation of `duration` (
215
- [[time.duration]]), and `abs_time` denotes a value of an instantiation
216
- of `time_point` ([[time.point]])).
217
 
218
  ``` cpp
219
  m.try_lock_for(rel_time)
220
  ```
221
 
222
  *Effects:* Attempts to acquire a lock for the current execution agent
223
- within the relative timeout ([[thread.req.timing]]) specified by
224
- `rel_time`. The function shall not return within the timeout specified
225
- by `rel_time` unless it has obtained a lock on `m` for the current
226
- execution agent. If an exception is thrown then a lock shall not have
227
- been acquired for the current execution agent.
228
 
229
  *Return type:* `bool`.
230
 
231
  *Returns:* `true` if the lock was acquired, `false` otherwise.
232
 
233
  ``` cpp
234
  m.try_lock_until(abs_time)
235
  ```
236
 
237
  *Effects:* Attempts to acquire a lock for the current execution agent
238
- before the absolute timeout ([[thread.req.timing]]) specified by
239
- `abs_time`. The function shall not return before the timeout specified
240
- by `abs_time` unless it has obtained a lock on `m` for the current
241
- execution agent. If an exception is thrown then a lock shall not have
242
- been acquired for the current execution agent.
243
 
244
  *Return type:* `bool`.
245
 
246
  *Returns:* `true` if the lock was acquired, `false` otherwise.
247
 
248
- ### `decay_copy` <a id="thread.decaycopy">[[thread.decaycopy]]</a>
249
 
250
- In several places in this Clause the operation `DECAY_COPY(x)` is used.
251
- All such uses mean call the function `decay_copy(x)` and use the result,
252
- where `decay_copy` is defined as follows:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
 
254
  ``` cpp
255
- template <class T> decay_t<T> decay_copy(T&& v)
256
- { return std::forward<T>(v); }
257
  ```
258
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
259
  ## Threads <a id="thread.threads">[[thread.threads]]</a>
260
 
261
  [[thread.threads]] describes components that can be used to create and
262
  manage threads.
263
 
@@ -265,15 +699,21 @@ manage threads.
265
  system threads. — *end note*]
266
 
267
  ### Header `<thread>` synopsis <a id="thread.syn">[[thread.syn]]</a>
268
 
269
  ``` cpp
 
 
 
270
  namespace std {
271
  class thread;
272
 
273
  void swap(thread& x, thread& y) noexcept;
274
 
 
 
 
275
  namespace this_thread {
276
  thread::id get_id() noexcept;
277
 
278
  void yield() noexcept;
279
  template<class Clock, class Duration>
@@ -303,33 +743,33 @@ successful call to `detach` or `join`. — *end note*]
303
 
304
  ``` cpp
305
  namespace std {
306
  class thread {
307
  public:
308
- // types:
309
  class id;
310
- using native_handle_type = implementation-defined; // See~[thread.req.native]
311
 
312
- // construct/copy/destroy:
313
  thread() noexcept;
314
  template<class F, class... Args> explicit thread(F&& f, Args&&... args);
315
  ~thread();
316
  thread(const thread&) = delete;
317
  thread(thread&&) noexcept;
318
  thread& operator=(const thread&) = delete;
319
  thread& operator=(thread&&) noexcept;
320
 
321
- // members:
322
  void swap(thread&) noexcept;
323
  bool joinable() const noexcept;
324
  void join();
325
  void detach();
326
  id get_id() const noexcept;
327
- native_handle_type native_handle(); // See~[thread.req.native]
328
 
329
- // static members:
330
- static unsigned hardware_concurrency() noexcept;
331
  };
332
  }
333
  ```
334
 
335
  #### Class `thread::id` <a id="thread.thread.id">[[thread.thread.id]]</a>
@@ -340,150 +780,129 @@ namespace std {
340
  public:
341
  id() noexcept;
342
  };
343
 
344
  bool operator==(thread::id x, thread::id y) noexcept;
345
- bool operator!=(thread::id x, thread::id y) noexcept;
346
- bool operator<(thread::id x, thread::id y) noexcept;
347
- bool operator<=(thread::id x, thread::id y) noexcept;
348
- bool operator>(thread::id x, thread::id y) noexcept;
349
- bool operator>=(thread::id x, thread::id y) noexcept;
350
 
351
  template<class charT, class traits>
352
  basic_ostream<charT, traits>&
353
  operator<<(basic_ostream<charT, traits>& out, thread::id id);
354
 
355
- // Hash support
356
  template<class T> struct hash;
357
  template<> struct hash<thread::id>;
358
  }
359
  ```
360
 
361
  An object of type `thread::id` provides a unique identifier for each
362
  thread of execution and a single distinct value for all `thread` objects
363
- that do not represent a thread of execution ([[thread.thread.class]]).
364
  Each thread of execution has an associated `thread::id` object that is
365
  not equal to the `thread::id` object of any other thread of execution
366
  and that is not equal to the `thread::id` object of any `thread` object
367
  that does not represent threads of execution.
368
 
369
- `thread::id` shall be a trivially copyable class (Clause  [[class]]).
370
- The library may reuse the value of a `thread::id` of a terminated thread
371
- that can no longer be joined.
372
 
373
  [*Note 1*: Relational operators allow `thread::id` objects to be used
374
  as keys in associative containers. — *end note*]
375
 
376
  ``` cpp
377
  id() noexcept;
378
  ```
379
 
380
- *Effects:* Constructs an object of type `id`.
381
-
382
- *Postconditions:* The constructed object does not represent a thread of
383
  execution.
384
 
385
  ``` cpp
386
  bool operator==(thread::id x, thread::id y) noexcept;
387
  ```
388
 
389
  *Returns:* `true` only if `x` and `y` represent the same thread of
390
  execution or neither `x` nor `y` represents a thread of execution.
391
 
392
  ``` cpp
393
- bool operator!=(thread::id x, thread::id y) noexcept;
394
  ```
395
 
396
- *Returns:* `!(x == y)`
 
397
 
398
- ``` cpp
399
- bool operator<(thread::id x, thread::id y) noexcept;
400
- ```
401
-
402
- *Returns:* A value such that `operator<` is a total ordering as
403
- described in  [[alg.sorting]].
404
-
405
- ``` cpp
406
- bool operator<=(thread::id x, thread::id y) noexcept;
407
- ```
408
-
409
- *Returns:* `!(y < x)`.
410
-
411
- ``` cpp
412
- bool operator>(thread::id x, thread::id y) noexcept;
413
- ```
414
-
415
- *Returns:* `y < x`.
416
-
417
- ``` cpp
418
- bool operator>=(thread::id x, thread::id y) noexcept;
419
- ```
420
-
421
- *Returns:* `!(x < y)`.
422
 
423
  ``` cpp
424
  template<class charT, class traits>
425
  basic_ostream<charT, traits>&
426
  operator<< (basic_ostream<charT, traits>& out, thread::id id);
427
  ```
428
 
429
  *Effects:* Inserts an unspecified text representation of `id` into
430
  `out`. For two objects of type `thread::id` `x` and `y`, if `x == y` the
431
- `thread::id` objects shall have the same text representation and if
432
- `x != y` the `thread::id` objects shall have distinct text
433
- representations.
434
 
435
  *Returns:* `out`.
436
 
437
  ``` cpp
438
  template<> struct hash<thread::id>;
439
  ```
440
 
441
- The specialization is enabled ([[unord.hash]]).
442
 
443
- #### `thread` constructors <a id="thread.thread.constr">[[thread.thread.constr]]</a>
444
 
445
  ``` cpp
446
  thread() noexcept;
447
  ```
448
 
449
- *Effects:* Constructs a `thread` object that does not represent a thread
450
- of execution.
451
 
452
- *Postconditions:* `get_id() == id()`.
453
 
454
  ``` cpp
455
  template<class F, class... Args> explicit thread(F&& f, Args&&... args);
456
  ```
457
 
458
- *Requires:*  `F` and each `Ti` in `Args` shall satisfy the
459
- `MoveConstructible` requirements.
460
- ` `*`INVOKE`*`( `*`DECAY_COPY`*`( std::forward<F>(f)), `*`DECAY_COPY`*`( std::forward<Args>(args))...)` ([[func.require]])
461
- shall be a valid expression.
462
-
463
- *Remarks:* This constructor shall not participate in overload resolution
464
- if `decay_t<F>` is the same type as `std::thread`.
465
-
466
- *Effects:*  Constructs an object of type `thread`. The new thread of
467
- execution executes
468
- ` `*`INVOKE`*`( `*`DECAY_COPY`*`( std::forward<F>(f)), `*`DECAY_COPY`*`( std::forward<Args>(args))...)`
469
- with the calls to *`DECAY_COPY`* being evaluated in the constructing
 
 
 
 
 
 
 
 
470
  thread. Any return value from this invocation is ignored.
471
 
472
  [*Note 1*: This implies that any exceptions not thrown from the
473
  invocation of the copy of `f` will be thrown in the constructing thread,
474
  not the new thread. — *end note*]
475
 
476
- If the invocation of
477
- ` `*`INVOKE`*`( `*`DECAY_COPY`*`( std::forward<F>(f)), `*`DECAY_COPY`*`( std::forward<Args>(args))...)`
478
- terminates with an uncaught exception, `terminate` shall be called.
479
 
480
  *Synchronization:* The completion of the invocation of the constructor
481
  synchronizes with the beginning of the invocation of the copy of `f`.
482
 
483
- *Postconditions:* `get_id() != id()`. `*this` represents the newly
484
- started thread.
485
 
486
  *Throws:* `system_error` if unable to start the new thread.
487
 
488
  *Error conditions:*
489
 
@@ -493,45 +912,43 @@ started thread.
493
 
494
  ``` cpp
495
  thread(thread&& x) noexcept;
496
  ```
497
 
498
- *Effects:* Constructs an object of type `thread` from `x`, and sets `x`
499
- to a default constructed state.
500
 
501
- *Postconditions:* `x.get_id() == id()` and `get_id()` returns the value
502
- of `x.get_id()` prior to the start of construction.
503
-
504
- #### `thread` destructor <a id="thread.thread.destr">[[thread.thread.destr]]</a>
505
 
506
  ``` cpp
507
  ~thread();
508
  ```
509
 
510
- If `joinable()`, calls `terminate()`. Otherwise, has no effects.
 
511
 
512
  [*Note 1*: Either implicitly detaching or joining a `joinable()` thread
513
  in its destructor could result in difficult to debug correctness (for
514
  detach) or performance (for join) bugs encountered only when an
515
  exception is thrown. Thus the programmer must ensure that the destructor
516
  is never executed while the thread is still joinable. — *end note*]
517
 
518
- #### `thread` assignment <a id="thread.thread.assign">[[thread.thread.assign]]</a>
519
 
520
  ``` cpp
521
  thread& operator=(thread&& x) noexcept;
522
  ```
523
 
524
  *Effects:* If `joinable()`, calls `terminate()`. Otherwise, assigns the
525
  state of `x` to `*this` and sets `x` to a default constructed state.
526
 
527
- *Postconditions:* `x.get_id() == id()` and `get_id()` returns the value
528
- of `x.get_id()` prior to the assignment.
529
 
530
  *Returns:* `*this`.
531
 
532
- #### `thread` members <a id="thread.thread.member">[[thread.thread.member]]</a>
533
 
534
  ``` cpp
535
  void swap(thread& x) noexcept;
536
  ```
537
 
@@ -545,24 +962,23 @@ bool joinable() const noexcept;
545
 
546
  ``` cpp
547
  void join();
548
  ```
549
 
550
- *Effects:*  Blocks until the thread represented by `*this` has
551
- completed.
552
 
553
  *Synchronization:* The completion of the thread represented by `*this`
554
- synchronizes with ([[intro.multithread]]) the corresponding successful
555
  `join()` return.
556
 
557
  [*Note 1*: Operations on `*this` are not synchronized. — *end note*]
558
 
559
- *Postconditions:* The thread represented by `*this` has completed.
560
  `get_id() == id()`.
561
 
562
  *Throws:* `system_error` when an exception is
563
- required ([[thread.req.exception]]).
564
 
565
  *Error conditions:*
566
 
567
  - `resource_deadlock_would_occur` — if deadlock is detected or
568
  `get_id() == this_thread::get_id()`.
@@ -575,16 +991,16 @@ void detach();
575
 
576
  *Effects:* The thread represented by `*this` continues execution without
577
  the calling thread blocking. When `detach()` returns, `*this` no longer
578
  represents the possibly continuing thread of execution. When the thread
579
  previously represented by `*this` ends execution, the implementation
580
- shall release any owned resources.
581
 
582
- *Postconditions:* `get_id() == id()`.
583
 
584
  *Throws:* `system_error` when an exception is
585
- required ([[thread.req.exception]]).
586
 
587
  *Error conditions:*
588
 
589
  - `no_such_process` — if the thread is not valid.
590
  - `invalid_argument` — if the thread is not joinable.
@@ -595,32 +1011,288 @@ id get_id() const noexcept;
595
 
596
  *Returns:* A default constructed `id` object if `*this` does not
597
  represent a thread, otherwise `this_thread::get_id()` for the thread of
598
  execution represented by `*this`.
599
 
600
- #### `thread` static members <a id="thread.thread.static">[[thread.thread.static]]</a>
601
 
602
  ``` cpp
603
  unsigned hardware_concurrency() noexcept;
604
  ```
605
 
606
  *Returns:* The number of hardware thread contexts.
607
 
608
  [*Note 1*: This value should only be considered to be a
609
  hint. — *end note*]
610
 
611
- If this value is not computable or well defined an implementation should
612
- return 0.
613
 
614
- #### `thread` specialized algorithms <a id="thread.thread.algorithm">[[thread.thread.algorithm]]</a>
615
 
616
  ``` cpp
617
  void swap(thread& x, thread& y) noexcept;
618
  ```
619
 
620
  *Effects:* As if by `x.swap(y)`.
621
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
622
  ### Namespace `this_thread` <a id="thread.thread.this">[[thread.thread.this]]</a>
623
 
624
  ``` cpp
625
  namespace std::this_thread {
626
  thread::id get_id() noexcept;
@@ -636,14 +1308,13 @@ namespace std::this_thread {
636
  ``` cpp
637
  thread::id this_thread::get_id() noexcept;
638
  ```
639
 
640
  *Returns:* An object of type `thread::id` that uniquely identifies the
641
- current thread of execution. No other thread of execution shall have
642
- this id and this thread of execution shall always have this id. The
643
- object returned shall not compare equal to a default constructed
644
- `thread::id`.
645
 
646
  ``` cpp
647
  void this_thread::yield() noexcept;
648
  ```
649
 
@@ -655,33 +1326,33 @@ void this_thread::yield() noexcept;
655
  template<class Clock, class Duration>
656
  void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
657
  ```
658
 
659
  *Effects:* Blocks the calling thread for the absolute
660
- timeout ([[thread.req.timing]]) specified by `abs_time`.
661
 
662
  *Synchronization:* None.
663
 
664
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
665
 
666
  ``` cpp
667
  template<class Rep, class Period>
668
  void sleep_for(const chrono::duration<Rep, Period>& rel_time);
669
  ```
670
 
671
  *Effects:* Blocks the calling thread for the relative
672
- timeout ([[thread.req.timing]]) specified by `rel_time`.
673
 
674
  *Synchronization:* None.
675
 
676
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
677
 
678
  ## Mutual exclusion <a id="thread.mutex">[[thread.mutex]]</a>
679
 
680
- This section provides mechanisms for mutual exclusion: mutexes, locks,
681
  and call once. These mechanisms ease the production of race-free
682
- programs ([[intro.multithread]]).
683
 
684
  ### Header `<mutex>` synopsis <a id="mutex.syn">[[mutex.syn]]</a>
685
 
686
  ``` cpp
687
  namespace std {
@@ -713,11 +1384,11 @@ namespace std {
713
  template<class Callable, class... Args>
714
  void call_once(once_flag& flag, Callable&& func, Args&&... args);
715
  }
716
  ```
717
 
718
- ### Header `<shared_mutex>` synopsis <a id="shared_mutex.syn">[[shared_mutex.syn]]</a>
719
 
720
  ``` cpp
721
  namespace std {
722
  class shared_mutex;
723
  class shared_timed_mutex;
@@ -730,128 +1401,129 @@ namespace std {
730
  ### Mutex requirements <a id="thread.mutex.requirements">[[thread.mutex.requirements]]</a>
731
 
732
  #### In general <a id="thread.mutex.requirements.general">[[thread.mutex.requirements.general]]</a>
733
 
734
  A mutex object facilitates protection against data races and allows safe
735
- synchronization of data between execution agents (
736
- [[thread.req.lockable]]). An execution agent *owns* a mutex from the
737
- time it successfully calls one of the lock functions until it calls
738
- unlock. Mutexes can be either recursive or non-recursive, and can grant
739
  simultaneous ownership to one or many execution agents. Both recursive
740
  and non-recursive mutexes are supplied.
741
 
742
  #### Mutex types <a id="thread.mutex.requirements.mutex">[[thread.mutex.requirements.mutex]]</a>
743
 
744
  The *mutex types* are the standard library types `mutex`,
745
  `recursive_mutex`, `timed_mutex`, `recursive_timed_mutex`,
746
- `shared_mutex`, and `shared_timed_mutex`. They shall meet the
747
- requirements set out in this section. In this description, `m` denotes
748
- an object of a mutex type.
749
 
750
- The mutex types shall meet the `Lockable` requirements (
751
- [[thread.req.lockable.req]]).
752
 
753
- The mutex types shall be `DefaultConstructible` and `Destructible`. If
754
- initialization of an object of a mutex type fails, an exception of type
755
- `system_error` shall be thrown. The mutex types shall not be copyable or
756
- movable.
757
 
758
  The error conditions for error codes, if any, reported by member
759
- functions of the mutex types shall be:
760
 
761
  - `resource_unavailable_try_again` — if any native handle type
762
  manipulated is not available.
763
  - `operation_not_permitted` — if the thread does not have the privilege
764
  to perform the operation.
765
  - `invalid_argument` — if any native handle type manipulated as part of
766
  mutex construction is incorrect.
767
 
768
- The implementation shall provide lock and unlock operations, as
769
- described below. For purposes of determining the existence of a data
770
- race, these behave as atomic operations ([[intro.multithread]]). The
771
- lock and unlock operations on a single mutex shall appear to occur in a
772
- single total order.
773
 
774
- [*Note 1*: This can be viewed as the modification order (
775
- [[intro.multithread]]) of the mutex. — *end note*]
776
 
777
  [*Note 2*: Construction and destruction of an object of a mutex type
778
  need not be thread-safe; other synchronization should be used to ensure
779
  that mutex objects are initialized and visible to other
780
  threads. — *end note*]
781
 
782
- The expression `m.lock()` shall be well-formed and have the following
783
  semantics:
784
 
785
- *Requires:* If `m` is of type `mutex`, `timed_mutex`, `shared_mutex`, or
786
- `shared_timed_mutex`, the calling thread does not own the mutex.
 
787
 
788
  *Effects:* Blocks the calling thread until ownership of the mutex can be
789
  obtained for the calling thread.
790
 
791
- *Postconditions:* The calling thread owns the mutex.
792
 
793
  *Return type:* `void`.
794
 
795
- *Synchronization:* Prior `unlock()` operations on the same object shall
796
- *synchronize with* ([[intro.multithread]]) this operation.
797
 
798
  *Throws:* `system_error` when an exception is
799
- required ([[thread.req.exception]]).
800
 
801
  *Error conditions:*
802
 
803
  - `operation_not_permitted` — if the thread does not have the privilege
804
  to perform the operation.
805
  - `resource_deadlock_would_occur` — if the implementation detects that a
806
  deadlock would occur.
807
 
808
- The expression `m.try_lock()` shall be well-formed and have the
809
- following semantics:
810
 
811
- *Requires:* If `m` is of type `mutex`, `timed_mutex`, `shared_mutex`, or
812
- `shared_timed_mutex`, the calling thread does not own the mutex.
 
813
 
814
  *Effects:* Attempts to obtain ownership of the mutex for the calling
815
  thread without blocking. If ownership is not obtained, there is no
816
  effect and `try_lock()` immediately returns. An implementation may fail
817
  to obtain the lock even if it is not held by any other thread.
818
 
819
  [*Note 1*: This spurious failure is normally uncommon, but allows
820
- interesting implementations based on a simple compare and exchange
821
- (Clause  [[atomics]]). — *end note*]
822
 
823
  An implementation should ensure that `try_lock()` does not consistently
824
  return `false` in the absence of contending mutex acquisitions.
825
 
826
  *Return type:* `bool`.
827
 
828
  *Returns:* `true` if ownership of the mutex was obtained for the calling
829
  thread, otherwise `false`.
830
 
831
  *Synchronization:* If `try_lock()` returns `true`, prior `unlock()`
832
- operations on the same object *synchronize
833
- with* ([[intro.multithread]]) this operation.
834
 
835
  [*Note 2*: Since `lock()` does not synchronize with a failed subsequent
836
  `try_lock()`, the visibility rules are weak enough that little would be
837
  known about the state after a failure, even in the absence of spurious
838
  failures. — *end note*]
839
 
840
  *Throws:* Nothing.
841
 
842
- The expression `m.unlock()` shall be well-formed and have the following
843
  semantics:
844
 
845
- *Requires:* The calling thread shall own the mutex.
846
 
847
  *Effects:* Releases the calling thread’s ownership of the mutex.
848
 
849
  *Return type:* `void`.
850
 
851
  *Synchronization:* This operation synchronizes
852
- with ([[intro.multithread]]) subsequent lock operations that obtain
853
  ownership on the same object.
854
 
855
  *Throws:* Nothing.
856
 
857
  ##### Class `mutex` <a id="thread.mutex.class">[[thread.mutex.class]]</a>
@@ -868,12 +1540,12 @@ namespace std {
868
 
869
  void lock();
870
  bool try_lock();
871
  void unlock();
872
 
873
- using native_handle_type = implementation-defined; // See~[thread.req.native]
874
- native_handle_type native_handle(); // See~[thread.req.native]
875
  };
876
  }
877
  ```
878
 
879
  The class `mutex` provides a non-recursive mutex with exclusive
@@ -889,17 +1561,17 @@ that it is no longer in use, unlock it, and destroy it, before thread
889
  required to handle such scenarios correctly, as long as thread `A`
890
  doesn’t access the mutex after the unlock call returns. These cases
891
  typically occur when a reference-counted object contains a mutex that is
892
  used to protect the reference count. — *end note*]
893
 
894
- The class `mutex` shall satisfy all of the mutex requirements (
895
- [[thread.mutex.requirements]]). It shall be a standard-layout class
896
- (Clause  [[class]]).
897
 
898
- [*Note 4*: A program may deadlock if the thread that owns a `mutex`
899
  object calls `lock()` on that object. If the implementation can detect
900
- the deadlock, a `resource_deadlock_would_occur` error condition may be
901
  observed. — *end note*]
902
 
903
  The behavior of a program is undefined if it destroys a `mutex` object
904
  owned by any thread or a thread terminates while owning a `mutex`
905
  object.
@@ -918,92 +1590,92 @@ namespace std {
918
 
919
  void lock();
920
  bool try_lock() noexcept;
921
  void unlock();
922
 
923
- using native_handle_type = implementation-defined; // See~[thread.req.native]
924
- native_handle_type native_handle(); // See~[thread.req.native]
925
  };
926
  }
927
  ```
928
 
929
  The class `recursive_mutex` provides a recursive mutex with exclusive
930
  ownership semantics. If one thread owns a `recursive_mutex` object,
931
  attempts by another thread to acquire ownership of that object will fail
932
  (for `try_lock()`) or block (for `lock()`) until the first thread has
933
  completely released ownership.
934
 
935
- The class `recursive_mutex` shall satisfy all of the mutex
936
- requirements ([[thread.mutex.requirements]]). It shall be a
937
- standard-layout class (Clause  [[class]]).
938
 
939
  A thread that owns a `recursive_mutex` object may acquire additional
940
  levels of ownership by calling `lock()` or `try_lock()` on that object.
941
  It is unspecified how many levels of ownership may be acquired by a
942
  single thread. If a thread has already acquired the maximum level of
943
  ownership for a `recursive_mutex` object, additional calls to
944
- `try_lock()` shall fail, and additional calls to `lock()` shall throw an
945
- exception of type `system_error`. A thread shall call `unlock()` once
946
- for each level of ownership acquired by calls to `lock()` and
947
- `try_lock()`. Only when all levels of ownership have been released may
948
- ownership be acquired by another thread.
949
 
950
  The behavior of a program is undefined if:
951
 
952
  - it destroys a `recursive_mutex` object owned by any thread or
953
  - a thread terminates while owning a `recursive_mutex` object.
954
 
955
  #### Timed mutex types <a id="thread.timedmutex.requirements">[[thread.timedmutex.requirements]]</a>
956
 
957
  The *timed mutex types* are the standard library types `timed_mutex`,
958
- `recursive_timed_mutex`, and `shared_timed_mutex`. They shall meet the
959
  requirements set out below. In this description, `m` denotes an object
960
  of a mutex type, `rel_time` denotes an object of an instantiation of
961
- `duration` ([[time.duration]]), and `abs_time` denotes an object of an
962
- instantiation of `time_point` ([[time.point]]).
963
 
964
- The timed mutex types shall meet the `TimedLockable` requirements (
965
- [[thread.req.lockable.timed]]).
966
 
967
- The expression `m.try_lock_for(rel_time)` shall be well-formed and have
968
- the following semantics:
969
 
970
- *Requires:* If `m` is of type `timed_mutex` or `shared_timed_mutex`, the
971
- calling thread does not own the mutex.
972
 
973
  *Effects:* The function attempts to obtain ownership of the mutex within
974
- the relative timeout ([[thread.req.timing]]) specified by `rel_time`.
975
- If the time specified by `rel_time` is less than or equal to
976
  `rel_time.zero()`, the function attempts to obtain ownership without
977
- blocking (as if by calling `try_lock()`). The function shall return
978
- within the timeout specified by `rel_time` only if it has obtained
979
- ownership of the mutex object.
980
 
981
  [*Note 1*: As with `try_lock()`, there is no guarantee that ownership
982
  will be obtained if the lock is available, but implementations are
983
  expected to make a strong effort to do so. — *end note*]
984
 
985
  *Return type:* `bool`.
986
 
987
  *Returns:* `true` if ownership was obtained, otherwise `false`.
988
 
989
  *Synchronization:* If `try_lock_for()` returns `true`, prior `unlock()`
990
- operations on the same object *synchronize
991
- with* ([[intro.multithread]]) this operation.
992
 
993
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
994
 
995
- The expression `m.try_lock_until(abs_time)` shall be well-formed and
996
- have the following semantics:
997
 
998
- *Requires:* If `m` is of type `timed_mutex` or `shared_timed_mutex`, the
999
- calling thread does not own the mutex.
1000
 
1001
  *Effects:* The function attempts to obtain ownership of the mutex. If
1002
  `abs_time` has already passed, the function attempts to obtain ownership
1003
- without blocking (as if by calling `try_lock()`). The function shall
1004
- return before the absolute timeout ([[thread.req.timing]]) specified by
1005
  `abs_time` only if it has obtained ownership of the mutex object.
1006
 
1007
  [*Note 2*: As with `try_lock()`, there is no guarantee that ownership
1008
  will be obtained if the lock is available, but implementations are
1009
  expected to make a strong effort to do so. — *end note*]
@@ -1012,13 +1684,13 @@ expected to make a strong effort to do so. — *end note*]
1012
 
1013
  *Returns:* `true` if ownership was obtained, otherwise `false`.
1014
 
1015
  *Synchronization:* If `try_lock_until()` returns `true`, prior
1016
  `unlock()` operations on the same object *synchronize
1017
- with* ([[intro.multithread]]) this operation.
1018
 
1019
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
1020
 
1021
  ##### Class `timed_mutex` <a id="thread.timedmutex.class">[[thread.timedmutex.class]]</a>
1022
 
1023
  ``` cpp
1024
  namespace std {
@@ -1036,12 +1708,12 @@ namespace std {
1036
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
1037
  template<class Clock, class Duration>
1038
  bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
1039
  void unlock();
1040
 
1041
- using native_handle_type = implementation-defined; // See~[thread.req.native]
1042
- native_handle_type native_handle(); // See~[thread.req.native]
1043
  };
1044
  }
1045
  ```
1046
 
1047
  The class `timed_mutex` provides a non-recursive mutex with exclusive
@@ -1050,13 +1722,13 @@ by another thread to acquire ownership of that object will fail (for
1050
  `try_lock()`) or block (for `lock()`, `try_lock_for()`, and
1051
  `try_lock_until()`) until the owning thread has released ownership with
1052
  a call to `unlock()` or the call to `try_lock_for()` or
1053
  `try_lock_until()` times out (having failed to obtain ownership).
1054
 
1055
- The class `timed_mutex` shall satisfy all of the timed mutex
1056
- requirements ([[thread.timedmutex.requirements]]). It shall be a
1057
- standard-layout class (Clause  [[class]]).
1058
 
1059
  The behavior of a program is undefined if:
1060
 
1061
  - it destroys a `timed_mutex` object owned by any thread,
1062
  - a thread that owns a `timed_mutex` object calls `lock()`,
@@ -1082,12 +1754,12 @@ namespace std {
1082
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
1083
  template<class Clock, class Duration>
1084
  bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
1085
  void unlock();
1086
 
1087
- using native_handle_type = implementation-defined; // See~[thread.req.native]
1088
- native_handle_type native_handle(); // See~[thread.req.native]
1089
  };
1090
  }
1091
  ```
1092
 
1093
  The class `recursive_timed_mutex` provides a recursive mutex with
@@ -1096,99 +1768,99 @@ exclusive ownership semantics. If one thread owns a
1096
  ownership of that object will fail (for `try_lock()`) or block (for
1097
  `lock()`, `try_lock_for()`, and `try_lock_until()`) until the owning
1098
  thread has completely released ownership or the call to `try_lock_for()`
1099
  or `try_lock_until()` times out (having failed to obtain ownership).
1100
 
1101
- The class `recursive_timed_mutex` shall satisfy all of the timed mutex
1102
- requirements ([[thread.timedmutex.requirements]]). It shall be a
1103
- standard-layout class (Clause  [[class]]).
1104
 
1105
  A thread that owns a `recursive_timed_mutex` object may acquire
1106
  additional levels of ownership by calling `lock()`, `try_lock()`,
1107
  `try_lock_for()`, or `try_lock_until()` on that object. It is
1108
  unspecified how many levels of ownership may be acquired by a single
1109
  thread. If a thread has already acquired the maximum level of ownership
1110
  for a `recursive_timed_mutex` object, additional calls to `try_lock()`,
1111
- `try_lock_for()`, or `try_lock_until()` shall fail, and additional calls
1112
- to `lock()` shall throw an exception of type `system_error`. A thread
1113
- shall call `unlock()` once for each level of ownership acquired by calls
1114
- to `lock()`, `try_lock()`, `try_lock_for()`, and `try_lock_until()`.
1115
- Only when all levels of ownership have been released may ownership of
1116
- the object be acquired by another thread.
1117
 
1118
  The behavior of a program is undefined if:
1119
 
1120
  - it destroys a `recursive_timed_mutex` object owned by any thread, or
1121
  - a thread terminates while owning a `recursive_timed_mutex` object.
1122
 
1123
  #### Shared mutex types <a id="thread.sharedmutex.requirements">[[thread.sharedmutex.requirements]]</a>
1124
 
1125
  The standard library types `shared_mutex` and `shared_timed_mutex` are
1126
- *shared mutex types*. Shared mutex types shall meet the requirements of
1127
- mutex types ([[thread.mutex.requirements.mutex]]), and additionally
1128
- shall meet the requirements set out below. In this description, `m`
1129
- denotes an object of a shared mutex type.
1130
 
1131
  In addition to the exclusive lock ownership mode specified in 
1132
  [[thread.mutex.requirements.mutex]], shared mutex types provide a
1133
  *shared lock* ownership mode. Multiple execution agents can
1134
  simultaneously hold a shared lock ownership of a shared mutex type. But
1135
- no execution agent shall hold a shared lock while another execution
1136
- agent holds an exclusive lock on the same shared mutex type, and
1137
- vice-versa. The maximum number of execution agents which can share a
1138
- shared lock on a single shared mutex type is unspecified, but shall be
1139
- at least 10000. If more than the maximum number of execution agents
1140
- attempt to obtain a shared lock, the excess execution agents shall block
1141
- until the number of shared locks are reduced below the maximum amount by
1142
- other execution agents releasing their shared lock.
1143
 
1144
- The expression `m.lock_shared()` shall be well-formed and have the
1145
- following semantics:
1146
 
1147
- *Requires:* The calling thread has no ownership of the mutex.
1148
 
1149
  *Effects:* Blocks the calling thread until shared ownership of the mutex
1150
  can be obtained for the calling thread. If an exception is thrown then a
1151
- shared lock shall not have been acquired for the current thread.
1152
 
1153
- *Postconditions:* The calling thread has a shared lock on the mutex.
1154
 
1155
  *Return type:* `void`.
1156
 
1157
- *Synchronization:* Prior `unlock()` operations on the same object shall
1158
- synchronize with ([[intro.multithread]]) this operation.
1159
 
1160
  *Throws:* `system_error` when an exception is
1161
- required ([[thread.req.exception]]).
1162
 
1163
  *Error conditions:*
1164
 
1165
  - `operation_not_permitted` — if the thread does not have the privilege
1166
  to perform the operation.
1167
  - `resource_deadlock_would_occur` — if the implementation detects that a
1168
  deadlock would occur.
1169
 
1170
- The expression `m.unlock_shared()` shall be well-formed and have the
1171
- following semantics:
1172
 
1173
- *Requires:* The calling thread shall hold a shared lock on the mutex.
1174
 
1175
  *Effects:* Releases a shared lock on the mutex held by the calling
1176
  thread.
1177
 
1178
  *Return type:* `void`.
1179
 
1180
  *Synchronization:* This operation synchronizes
1181
- with ([[intro.multithread]]) subsequent `lock()` operations that obtain
1182
  ownership on the same object.
1183
 
1184
  *Throws:* Nothing.
1185
 
1186
- The expression `m.try_lock_shared()` shall be well-formed and have the
1187
  following semantics:
1188
 
1189
- *Requires:* The calling thread has no ownership of the mutex.
1190
 
1191
  *Effects:* Attempts to obtain shared ownership of the mutex for the
1192
  calling thread without blocking. If shared ownership is not obtained,
1193
  there is no effect and `try_lock_shared()` immediately returns. An
1194
  implementation may fail to obtain the lock even if it is not held by any
@@ -1199,15 +1871,15 @@ other thread.
1199
  *Returns:* `true` if the shared ownership lock was acquired, `false`
1200
  otherwise.
1201
 
1202
  *Synchronization:* If `try_lock_shared()` returns `true`, prior
1203
  `unlock()` operations on the same object synchronize
1204
- with ([[intro.multithread]]) this operation.
1205
 
1206
  *Throws:* Nothing.
1207
 
1208
- ##### Class shared_mutex <a id="thread.sharedmutex.class">[[thread.sharedmutex.class]]</a>
1209
 
1210
  ``` cpp
1211
  namespace std {
1212
  class shared_mutex {
1213
  public:
@@ -1215,32 +1887,32 @@ namespace std {
1215
  ~shared_mutex();
1216
 
1217
  shared_mutex(const shared_mutex&) = delete;
1218
  shared_mutex& operator=(const shared_mutex&) = delete;
1219
 
1220
- // Exclusive ownership
1221
  void lock(); // blocking
1222
  bool try_lock();
1223
  void unlock();
1224
 
1225
- // Shared ownership
1226
  void lock_shared(); // blocking
1227
  bool try_lock_shared();
1228
  void unlock_shared();
1229
 
1230
- using native_handle_type = implementation-defined; // See~[thread.req.native]
1231
- native_handle_type native_handle(); // See~[thread.req.native]
1232
  };
1233
  }
1234
  ```
1235
 
1236
  The class `shared_mutex` provides a non-recursive mutex with shared
1237
  ownership semantics.
1238
 
1239
- The class `shared_mutex` shall satisfy all of the shared mutex
1240
- requirements ([[thread.sharedmutex.requirements]]). It shall be a
1241
- standard-layout class (Clause  [[class]]).
1242
 
1243
  The behavior of a program is undefined if:
1244
 
1245
  - it destroys a `shared_mutex` object owned by any thread,
1246
  - a thread attempts to recursively gain any ownership of a
@@ -1251,76 +1923,76 @@ The behavior of a program is undefined if:
1251
  `shared_mutex` may be a synonym for `shared_timed_mutex`.
1252
 
1253
  #### Shared timed mutex types <a id="thread.sharedtimedmutex.requirements">[[thread.sharedtimedmutex.requirements]]</a>
1254
 
1255
  The standard library type `shared_timed_mutex` is a *shared timed mutex
1256
- type*. Shared timed mutex types shall meet the requirements of timed
1257
- mutex types ([[thread.timedmutex.requirements]]), shared mutex types (
1258
- [[thread.sharedmutex.requirements]]), and additionally shall meet the
1259
  requirements set out below. In this description, `m` denotes an object
1260
  of a shared timed mutex type, `rel_type` denotes an object of an
1261
- instantiation of `duration` ([[time.duration]]), and `abs_time` denotes
1262
- an object of an instantiation of `time_point` ([[time.point]]).
1263
 
1264
- The expression `m.try_lock_shared_for(rel_time)` shall be well-formed
1265
- and have the following semantics:
1266
 
1267
- *Requires:* The calling thread has no ownership of the mutex.
1268
 
1269
  *Effects:* Attempts to obtain shared lock ownership for the calling
1270
- thread within the relative timeout ([[thread.req.timing]]) specified by
1271
  `rel_time`. If the time specified by `rel_time` is less than or equal to
1272
  `rel_time.zero()`, the function attempts to obtain ownership without
1273
- blocking (as if by calling `try_lock_shared()`). The function shall
1274
- return within the timeout specified by `rel_time` only if it has
1275
- obtained shared ownership of the mutex object.
1276
 
1277
  [*Note 1*: As with `try_lock()`, there is no guarantee that ownership
1278
  will be obtained if the lock is available, but implementations are
1279
  expected to make a strong effort to do so. — *end note*]
1280
 
1281
- If an exception is thrown then a shared lock shall not have been
1282
- acquired for the current thread.
1283
 
1284
  *Return type:* `bool`.
1285
 
1286
  *Returns:* `true` if the shared lock was acquired, `false` otherwise.
1287
 
1288
  *Synchronization:* If `try_lock_shared_for()` returns `true`, prior
1289
  `unlock()` operations on the same object synchronize
1290
- with ([[intro.multithread]]) this operation.
1291
 
1292
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
1293
 
1294
- The expression `m.try_lock_shared_until(abs_time)` shall be well-formed
1295
- and have the following semantics:
1296
 
1297
- *Requires:* The calling thread has no ownership of the mutex.
1298
 
1299
  *Effects:* The function attempts to obtain shared ownership of the
1300
  mutex. If `abs_time` has already passed, the function attempts to obtain
1301
  shared ownership without blocking (as if by calling
1302
- `try_lock_shared()`). The function shall return before the absolute
1303
- timeout ([[thread.req.timing]]) specified by `abs_time` only if it has
1304
  obtained shared ownership of the mutex object.
1305
 
1306
  [*Note 2*: As with `try_lock()`, there is no guarantee that ownership
1307
  will be obtained if the lock is available, but implementations are
1308
  expected to make a strong effort to do so. — *end note*]
1309
 
1310
- If an exception is thrown then a shared lock shall not have been
1311
- acquired for the current thread.
1312
 
1313
  *Return type:* `bool`.
1314
 
1315
  *Returns:* `true` if the shared lock was acquired, `false` otherwise.
1316
 
1317
  *Synchronization:* If `try_lock_shared_until()` returns `true`, prior
1318
  `unlock()` operations on the same object synchronize
1319
- with ([[intro.multithread]]) this operation.
1320
 
1321
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
1322
 
1323
  ##### Class `shared_timed_mutex` <a id="thread.sharedtimedmutex.class">[[thread.sharedtimedmutex.class]]</a>
1324
 
1325
  ``` cpp
1326
  namespace std {
@@ -1330,39 +2002,37 @@ namespace std {
1330
  ~shared_timed_mutex();
1331
 
1332
  shared_timed_mutex(const shared_timed_mutex&) = delete;
1333
  shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;
1334
 
1335
- // Exclusive ownership
1336
  void lock(); // blocking
1337
  bool try_lock();
1338
  template<class Rep, class Period>
1339
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
1340
  template<class Clock, class Duration>
1341
  bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
1342
  void unlock();
1343
 
1344
- // Shared ownership
1345
  void lock_shared(); // blocking
1346
  bool try_lock_shared();
1347
  template<class Rep, class Period>
1348
- bool
1349
- try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time);
1350
  template<class Clock, class Duration>
1351
- bool
1352
- try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time);
1353
  void unlock_shared();
1354
  };
1355
  }
1356
  ```
1357
 
1358
  The class `shared_timed_mutex` provides a non-recursive mutex with
1359
  shared ownership semantics.
1360
 
1361
- The class `shared_timed_mutex` shall satisfy all of the shared timed
1362
- mutex requirements ([[thread.sharedtimedmutex.requirements]]). It shall
1363
- be a standard-layout class (Clause  [[class]]).
1364
 
1365
  The behavior of a program is undefined if:
1366
 
1367
  - it destroys a `shared_timed_mutex` object owned by any thread,
1368
  - a thread attempts to recursively gain any ownership of a
@@ -1418,41 +2088,37 @@ namespace std {
1418
  lock_guard& operator=(const lock_guard&) = delete;
1419
 
1420
  private:
1421
  mutex_type& pm; // exposition only
1422
  };
1423
-
1424
- template<class Mutex> lock_guard(lock_guard<Mutex>) -> lock_guard<Mutex>;
1425
  }
1426
  ```
1427
 
1428
  An object of type `lock_guard` controls the ownership of a lockable
1429
  object within a scope. A `lock_guard` object maintains ownership of a
1430
- lockable object throughout the `lock_guard` object’s lifetime (
1431
- [[basic.life]]). The behavior of a program is undefined if the lockable
1432
  object referenced by `pm` does not exist for the entire lifetime of the
1433
  `lock_guard` object. The supplied `Mutex` type shall meet the
1434
- `BasicLockable` requirements ([[thread.req.lockable.basic]]).
1435
 
1436
  ``` cpp
1437
  explicit lock_guard(mutex_type& m);
1438
  ```
1439
 
1440
- *Requires:* If `mutex_type` is not a recursive mutex, the calling thread
1441
- does not own the mutex `m`.
1442
 
1443
- *Effects:* As if by `m.lock()`.
1444
-
1445
- *Postconditions:* `&pm == &m`
1446
 
1447
  ``` cpp
1448
  lock_guard(mutex_type& m, adopt_lock_t);
1449
  ```
1450
 
1451
- *Requires:* The calling thread owns the mutex `m`.
1452
 
1453
- *Postconditions:* `&pm == &m`
1454
 
1455
  *Throws:* Nothing.
1456
 
1457
  ``` cpp
1458
  ~lock_guard();
@@ -1468,52 +2134,49 @@ namespace std {
1468
  class scoped_lock {
1469
  public:
1470
  using mutex_type = Mutex; // If MutexTypes... consists of the single type Mutex
1471
 
1472
  explicit scoped_lock(MutexTypes&... m);
1473
- explicit scoped_lock(MutexTypes&... m, adopt_lock_t);
1474
  ~scoped_lock();
1475
 
1476
  scoped_lock(const scoped_lock&) = delete;
1477
  scoped_lock& operator=(const scoped_lock&) = delete;
1478
 
1479
  private:
1480
  tuple<MutexTypes&...> pm; // exposition only
1481
  };
1482
-
1483
- template<class... MutexTypes>
1484
- scoped_lock(scoped_lock<MutexTypes...>) -> scoped_lock<MutexTypes...>;
1485
  }
1486
  ```
1487
 
1488
  An object of type `scoped_lock` controls the ownership of lockable
1489
  objects within a scope. A `scoped_lock` object maintains ownership of
1490
- lockable objects throughout the `scoped_lock` object’s lifetime (
1491
- [[basic.life]]). The behavior of a program is undefined if the lockable
1492
  objects referenced by `pm` do not exist for the entire lifetime of the
1493
  `scoped_lock` object. When `sizeof...(MutexTypes)` is `1`, the supplied
1494
- `Mutex` type shall meet the `BasicLockable` requirements (
1495
- [[thread.req.lockable.basic]]). Otherwise, each of the mutex types shall
1496
- meet the `Lockable` requirements ([[thread.req.lockable.req]]).
1497
 
1498
  ``` cpp
1499
  explicit scoped_lock(MutexTypes&... m);
1500
  ```
1501
 
1502
- *Requires:* If a `MutexTypes` type is not a recursive mutex, the calling
1503
- thread does not own the corresponding mutex element of `m`.
1504
 
1505
  *Effects:* Initializes `pm` with `tie(m...)`. Then if
1506
  `sizeof...(MutexTypes)` is `0`, no effects. Otherwise if
1507
  `sizeof...(MutexTypes)` is `1`, then `m.lock()`. Otherwise,
1508
  `lock(m...)`.
1509
 
1510
  ``` cpp
1511
- explicit scoped_lock(MutexTypes&... m, adopt_lock_t);
1512
  ```
1513
 
1514
- *Requires:* The calling thread owns all the mutexes in `m`.
1515
 
1516
  *Effects:* Initializes `pm` with `tie(m...)`.
1517
 
1518
  *Throws:* Nothing.
1519
 
@@ -1574,12 +2237,10 @@ namespace std {
1574
  private:
1575
  mutex_type* pm; // exposition only
1576
  bool owns; // exposition only
1577
  };
1578
 
1579
- template<class Mutex> unique_lock(unique_lock<Mutex>) -> unique_lock<Mutex>;
1580
-
1581
  template<class Mutex>
1582
  void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
1583
  }
1584
  ```
1585
 
@@ -1588,123 +2249,113 @@ object within a scope. Ownership of the lockable object may be acquired
1588
  at construction or after construction, and may be transferred, after
1589
  acquisition, to another `unique_lock` object. Objects of type
1590
  `unique_lock` are not copyable but are movable. The behavior of a
1591
  program is undefined if the contained pointer `pm` is not null and the
1592
  lockable object pointed to by `pm` does not exist for the entire
1593
- remaining lifetime ([[basic.life]]) of the `unique_lock` object. The
1594
- supplied `Mutex` type shall meet the `BasicLockable` requirements (
1595
- [[thread.req.lockable.basic]]).
1596
 
1597
- [*Note 1*: `unique_lock<Mutex>` meets the `BasicLockable` requirements.
1598
- If `Mutex` meets the `Lockable` requirements (
1599
- [[thread.req.lockable.req]]), `unique_lock<Mutex>` also meets the
1600
- `Lockable` requirements; if `Mutex` meets the `TimedLockable`
1601
- requirements ([[thread.req.lockable.timed]]), `unique_lock<Mutex>` also
1602
- meets the `TimedLockable` requirements. — *end note*]
1603
 
1604
- ##### `unique_lock` constructors, destructor, and assignment <a id="thread.lock.unique.cons">[[thread.lock.unique.cons]]</a>
1605
 
1606
  ``` cpp
1607
  unique_lock() noexcept;
1608
  ```
1609
 
1610
- *Effects:* Constructs an object of type `unique_lock`.
1611
-
1612
- *Postconditions:* `pm == 0` and `owns == false`.
1613
 
1614
  ``` cpp
1615
  explicit unique_lock(mutex_type& m);
1616
  ```
1617
 
1618
- *Requires:* If `mutex_type` is not a recursive mutex the calling thread
1619
- does not own the mutex.
1620
 
1621
- *Effects:* Constructs an object of type `unique_lock` and calls
1622
- `m.lock()`.
1623
 
1624
- *Postconditions:* `pm == addressof(m)` and `owns == true`.
1625
 
1626
  ``` cpp
1627
  unique_lock(mutex_type& m, defer_lock_t) noexcept;
1628
  ```
1629
 
1630
- *Effects:* Constructs an object of type `unique_lock`.
1631
-
1632
- *Postconditions:* `pm == addressof(m)` and `owns == false`.
1633
 
1634
  ``` cpp
1635
  unique_lock(mutex_type& m, try_to_lock_t);
1636
  ```
1637
 
1638
- *Requires:* The supplied `Mutex` type shall meet the `Lockable`
1639
- requirements ([[thread.req.lockable.req]]). If `mutex_type` is not a
1640
  recursive mutex the calling thread does not own the mutex.
1641
 
1642
- *Effects:* Constructs an object of type `unique_lock` and calls
1643
- `m.try_lock()`.
1644
 
1645
- *Postconditions:* `pm == addressof(m)` and `owns == res`, where `res` is
1646
- the value returned by the call to `m.try_lock()`.
1647
 
1648
  ``` cpp
1649
  unique_lock(mutex_type& m, adopt_lock_t);
1650
  ```
1651
 
1652
- *Requires:* The calling thread owns the mutex.
1653
 
1654
- *Effects:* Constructs an object of type `unique_lock`.
1655
-
1656
- *Postconditions:* `pm == addressof(m)` and `owns == true`.
1657
 
1658
  *Throws:* Nothing.
1659
 
1660
  ``` cpp
1661
  template<class Clock, class Duration>
1662
  unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
1663
  ```
1664
 
1665
- *Requires:* If `mutex_type` is not a recursive mutex the calling thread
1666
- does not own the mutex. The supplied `Mutex` type shall meet the
1667
- `TimedLockable` requirements ([[thread.req.lockable.timed]]).
1668
 
1669
- *Effects:* Constructs an object of type `unique_lock` and calls
1670
- `m.try_lock_until(abs_time)`.
1671
 
1672
- *Postconditions:* `pm == addressof(m)` and `owns == res`, where `res` is
1673
- the value returned by the call to `m.try_lock_until(abs_time)`.
1674
 
1675
  ``` cpp
1676
  template<class Rep, class Period>
1677
  unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
1678
  ```
1679
 
1680
- *Requires:* If `mutex_type` is not a recursive mutex the calling thread
1681
- does not own the mutex. The supplied `Mutex` type shall meet the
1682
- `TimedLockable` requirements ([[thread.req.lockable.timed]]).
1683
 
1684
- *Effects:* Constructs an object of type `unique_lock` and calls
1685
- `m.try_lock_for(rel_time)`.
1686
 
1687
- *Postconditions:* `pm == addressof(m)` and `owns == res`, where `res` is
1688
- the value returned by the call to `m.try_lock_for(rel_time)`.
1689
 
1690
  ``` cpp
1691
  unique_lock(unique_lock&& u) noexcept;
1692
  ```
1693
 
1694
- *Postconditions:* `pm == u_p.pm` and `owns == u_p.owns` (where `u_p` is
1695
- the state of `u` just prior to this construction), `u.pm == 0` and
1696
  `u.owns == false`.
1697
 
1698
  ``` cpp
1699
  unique_lock& operator=(unique_lock&& u);
1700
  ```
1701
 
1702
  *Effects:* If `owns` calls `pm->unlock()`.
1703
 
1704
- *Postconditions:* `pm == u_p.pm` and `owns == u_p.owns` (where `u_p` is
1705
- the state of `u` just prior to this construction), `u.pm == 0` and
1706
  `u.owns == false`.
1707
 
1708
  [*Note 1*: With a recursive mutex it is possible for both `*this` and
1709
  `u` to own the same mutex before the assignment. In this case, `*this`
1710
  will own the mutex after the assignment and `u` will not. — *end note*]
@@ -1715,44 +2366,44 @@ will own the mutex after the assignment and `u` will not. — *end note*]
1715
  ~unique_lock();
1716
  ```
1717
 
1718
  *Effects:* If `owns` calls `pm->unlock()`.
1719
 
1720
- ##### `unique_lock` locking <a id="thread.lock.unique.locking">[[thread.lock.unique.locking]]</a>
1721
 
1722
  ``` cpp
1723
  void lock();
1724
  ```
1725
 
1726
  *Effects:* As if by `pm->lock()`.
1727
 
1728
- *Postconditions:* `owns == true`.
1729
 
1730
  *Throws:* Any exception thrown by `pm->lock()`. `system_error` when an
1731
- exception is required ([[thread.req.exception]]).
1732
 
1733
  *Error conditions:*
1734
 
1735
  - `operation_not_permitted` — if `pm` is `nullptr`.
1736
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
1737
 
1738
  ``` cpp
1739
  bool try_lock();
1740
  ```
1741
 
1742
- *Requires:* The supplied `Mutex` shall meet the `Lockable`
1743
- requirements ([[thread.req.lockable.req]]).
1744
 
1745
  *Effects:* As if by `pm->try_lock()`.
1746
 
1747
  *Returns:* The value returned by the call to `try_lock()`.
1748
 
1749
- *Postconditions:* `owns == res`, where `res` is the value returned by
1750
- the call to `try_lock()`.
1751
 
1752
  *Throws:* Any exception thrown by `pm->try_lock()`. `system_error` when
1753
- an exception is required ([[thread.req.exception]]).
1754
 
1755
  *Error conditions:*
1756
 
1757
  - `operation_not_permitted` — if `pm` is `nullptr`.
1758
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
@@ -1760,22 +2411,22 @@ an exception is required ([[thread.req.exception]]).
1760
  ``` cpp
1761
  template<class Clock, class Duration>
1762
  bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
1763
  ```
1764
 
1765
- *Requires:* The supplied `Mutex` type shall meet the `TimedLockable`
1766
- requirements ([[thread.req.lockable.timed]]).
1767
 
1768
  *Effects:* As if by `pm->try_lock_until(abs_time)`.
1769
 
1770
  *Returns:* The value returned by the call to `try_lock_until(abs_time)`.
1771
 
1772
- *Postconditions:* `owns == res`, where `res` is the value returned by
1773
- the call to `try_lock_until(abs_time)`.
1774
 
1775
  *Throws:* Any exception thrown by `pm->try_lock_until()`. `system_error`
1776
- when an exception is required ([[thread.req.exception]]).
1777
 
1778
  *Error conditions:*
1779
 
1780
  - `operation_not_permitted` — if `pm` is `nullptr`.
1781
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
@@ -1783,22 +2434,22 @@ when an exception is required ([[thread.req.exception]]).
1783
  ``` cpp
1784
  template<class Rep, class Period>
1785
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
1786
  ```
1787
 
1788
- *Requires:* The supplied `Mutex` type shall meet the `TimedLockable`
1789
- requirements ([[thread.req.lockable.timed]]).
1790
 
1791
  *Effects:* As if by `pm->try_lock_for(rel_time)`.
1792
 
1793
- *Returns:* The value returned by the call to `try_lock_until(rel_time)`.
1794
 
1795
- *Postconditions:* `owns == res`, where `res` is the value returned by
1796
- the call to `try_lock_for(rel_time)`.
1797
 
1798
  *Throws:* Any exception thrown by `pm->try_lock_for()`. `system_error`
1799
- when an exception is required ([[thread.req.exception]]).
1800
 
1801
  *Error conditions:*
1802
 
1803
  - `operation_not_permitted` — if `pm` is `nullptr`.
1804
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
@@ -1807,20 +2458,20 @@ when an exception is required ([[thread.req.exception]]).
1807
  void unlock();
1808
  ```
1809
 
1810
  *Effects:* As if by `pm->unlock()`.
1811
 
1812
- *Postconditions:* `owns == false`.
1813
 
1814
  *Throws:* `system_error` when an exception is
1815
- required ([[thread.req.exception]]).
1816
 
1817
  *Error conditions:*
1818
 
1819
  - `operation_not_permitted` — if on entry `owns` is `false`.
1820
 
1821
- ##### `unique_lock` modifiers <a id="thread.lock.unique.mod">[[thread.lock.unique.mod]]</a>
1822
 
1823
  ``` cpp
1824
  void swap(unique_lock& u) noexcept;
1825
  ```
1826
 
@@ -1830,20 +2481,20 @@ void swap(unique_lock& u) noexcept;
1830
  mutex_type* release() noexcept;
1831
  ```
1832
 
1833
  *Returns:* The previous value of `pm`.
1834
 
1835
- *Postconditions:* `pm == 0` and `owns == false`.
1836
 
1837
  ``` cpp
1838
  template<class Mutex>
1839
  void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
1840
  ```
1841
 
1842
  *Effects:* As if by `x.swap(y)`.
1843
 
1844
- ##### `unique_lock` observers <a id="thread.lock.unique.obs">[[thread.lock.unique.obs]]</a>
1845
 
1846
  ``` cpp
1847
  bool owns_lock() const noexcept;
1848
  ```
1849
 
@@ -1875,15 +2526,13 @@ namespace std {
1875
  explicit shared_lock(mutex_type& m); // blocking
1876
  shared_lock(mutex_type& m, defer_lock_t) noexcept;
1877
  shared_lock(mutex_type& m, try_to_lock_t);
1878
  shared_lock(mutex_type& m, adopt_lock_t);
1879
  template<class Clock, class Duration>
1880
- shared_lock(mutex_type& m,
1881
- const chrono::time_point<Clock, Duration>& abs_time);
1882
  template<class Rep, class Period>
1883
- shared_lock(mutex_type& m,
1884
- const chrono::duration<Rep, Period>& rel_time);
1885
  ~shared_lock();
1886
 
1887
  shared_lock(const shared_lock&) = delete;
1888
  shared_lock& operator=(const shared_lock&) = delete;
1889
 
@@ -1911,12 +2560,10 @@ namespace std {
1911
  private:
1912
  mutex_type* pm; // exposition only
1913
  bool owns; // exposition only
1914
  };
1915
 
1916
- template<class Mutex> shared_lock(shared_lock<Mutex>) -> shared_lock<Mutex>;
1917
-
1918
  template<class Mutex>
1919
  void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
1920
  }
1921
  ```
1922
 
@@ -1925,99 +2572,89 @@ lockable object within a scope. Shared ownership of the lockable object
1925
  may be acquired at construction or after construction, and may be
1926
  transferred, after acquisition, to another `shared_lock` object. Objects
1927
  of type `shared_lock` are not copyable but are movable. The behavior of
1928
  a program is undefined if the contained pointer `pm` is not null and the
1929
  lockable object pointed to by `pm` does not exist for the entire
1930
- remaining lifetime ([[basic.life]]) of the `shared_lock` object. The
1931
- supplied `Mutex` type shall meet the shared mutex requirements (
1932
- [[thread.sharedtimedmutex.requirements]]).
1933
 
1934
- [*Note 1*: `shared_lock<Mutex>` meets the `TimedLockable`
1935
- requirements ([[thread.req.lockable.timed]]). — *end note*]
1936
 
1937
- ##### `shared_lock` constructors, destructor, and assignment <a id="thread.lock.shared.cons">[[thread.lock.shared.cons]]</a>
1938
 
1939
  ``` cpp
1940
  shared_lock() noexcept;
1941
  ```
1942
 
1943
- *Effects:* Constructs an object of type `shared_lock`.
1944
-
1945
- *Postconditions:* `pm == nullptr` and `owns == false`.
1946
 
1947
  ``` cpp
1948
  explicit shared_lock(mutex_type& m);
1949
  ```
1950
 
1951
- *Requires:* The calling thread does not own the mutex for any ownership
1952
- mode.
1953
 
1954
- *Effects:* Constructs an object of type `shared_lock` and calls
1955
- `m.lock_shared()`.
1956
 
1957
- *Postconditions:* `pm == addressof(m)` and `owns == true`.
1958
 
1959
  ``` cpp
1960
  shared_lock(mutex_type& m, defer_lock_t) noexcept;
1961
  ```
1962
 
1963
- *Effects:* Constructs an object of type `shared_lock`.
1964
-
1965
- *Postconditions:* `pm == addressof(m)` and `owns == false`.
1966
 
1967
  ``` cpp
1968
  shared_lock(mutex_type& m, try_to_lock_t);
1969
  ```
1970
 
1971
- *Requires:* The calling thread does not own the mutex for any ownership
1972
- mode.
1973
 
1974
- *Effects:* Constructs an object of type `shared_lock` and calls
1975
- `m.try_lock_shared()`.
1976
 
1977
- *Postconditions:* `pm == addressof(m)` and `owns == res` where `res` is
1978
- the value returned by the call to `m.try_lock_shared()`.
1979
 
1980
  ``` cpp
1981
  shared_lock(mutex_type& m, adopt_lock_t);
1982
  ```
1983
 
1984
- *Requires:* The calling thread has shared ownership of the mutex.
1985
 
1986
- *Effects:* Constructs an object of type `shared_lock`.
1987
-
1988
- *Postconditions:* `pm == addressof(m)` and `owns == true`.
1989
 
1990
  ``` cpp
1991
  template<class Clock, class Duration>
1992
  shared_lock(mutex_type& m,
1993
  const chrono::time_point<Clock, Duration>& abs_time);
1994
  ```
1995
 
1996
- *Requires:* The calling thread does not own the mutex for any ownership
1997
- mode.
1998
 
1999
- *Effects:* Constructs an object of type `shared_lock` and calls
2000
- `m.try_lock_shared_until(abs_time)`.
2001
 
2002
- *Postconditions:* `pm == addressof(m)` and `owns == res` where `res` is
2003
- the value returned by the call to `m.try_lock_shared_until(abs_time)`.
2004
 
2005
  ``` cpp
2006
  template<class Rep, class Period>
2007
  shared_lock(mutex_type& m,
2008
  const chrono::duration<Rep, Period>& rel_time);
2009
  ```
2010
 
2011
- *Requires:* The calling thread does not own the mutex for any ownership
2012
- mode.
2013
 
2014
- *Effects:* Constructs an object of type `shared_lock` and calls
2015
- `m.try_lock_shared_for(rel_time)`.
2016
 
2017
- *Postconditions:* `pm == addressof(m)` and `owns == res` where `res` is
2018
- the value returned by the call to `m.try_lock_shared_for(rel_time)`.
2019
 
2020
  ``` cpp
2021
  ~shared_lock();
2022
  ```
2023
 
@@ -2025,36 +2662,36 @@ the value returned by the call to `m.try_lock_shared_for(rel_time)`.
2025
 
2026
  ``` cpp
2027
  shared_lock(shared_lock&& sl) noexcept;
2028
  ```
2029
 
2030
- *Postconditions:* `pm == sl_p.pm` and `owns == sl_p.owns` (where `sl_p`
2031
- is the state of `sl` just prior to this construction),
2032
- `sl.pm == nullptr` and `sl.owns == false`.
2033
 
2034
  ``` cpp
2035
  shared_lock& operator=(shared_lock&& sl) noexcept;
2036
  ```
2037
 
2038
  *Effects:* If `owns` calls `pm->unlock_shared()`.
2039
 
2040
- *Postconditions:* `pm == sl_p.pm` and `owns == sl_p.owns` (where `sl_p`
2041
- is the state of `sl` just prior to this assignment), `sl.pm == nullptr`
2042
- and `sl.owns == false`.
2043
 
2044
- ##### `shared_lock` locking <a id="thread.lock.shared.locking">[[thread.lock.shared.locking]]</a>
2045
 
2046
  ``` cpp
2047
  void lock();
2048
  ```
2049
 
2050
  *Effects:* As if by `pm->lock_shared()`.
2051
 
2052
- *Postconditions:* `owns == true`.
2053
 
2054
  *Throws:* Any exception thrown by `pm->lock_shared()`. `system_error`
2055
- when an exception is required ([[thread.req.exception]]).
2056
 
2057
  *Error conditions:*
2058
 
2059
  - `operation_not_permitted` — if `pm` is `nullptr`.
2060
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
@@ -2065,39 +2702,36 @@ bool try_lock();
2065
 
2066
  *Effects:* As if by `pm->try_lock_shared()`.
2067
 
2068
  *Returns:* The value returned by the call to `pm->try_lock_shared()`.
2069
 
2070
- *Postconditions:* `owns == res`, where `res` is the value returned by
2071
- the call to `pm->try_lock_shared()`.
2072
 
2073
  *Throws:* Any exception thrown by `pm->try_lock_shared()`.
2074
- `system_error` when an exception is
2075
- required ([[thread.req.exception]]).
2076
 
2077
  *Error conditions:*
2078
 
2079
  - `operation_not_permitted` — if `pm` is `nullptr`.
2080
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
2081
 
2082
  ``` cpp
2083
  template<class Clock, class Duration>
2084
- bool
2085
- try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
2086
  ```
2087
 
2088
  *Effects:* As if by `pm->try_lock_shared_until(abs_time)`.
2089
 
2090
  *Returns:* The value returned by the call to
2091
  `pm->try_lock_shared_until(abs_time)`.
2092
 
2093
- *Postconditions:* `owns == res`, where `res` is the value returned by
2094
- the call to `pm->try_lock_shared_until(abs_time)`.
2095
 
2096
  *Throws:* Any exception thrown by `pm->try_lock_shared_until(abs_time)`.
2097
- `system_error` when an exception is
2098
- required ([[thread.req.exception]]).
2099
 
2100
  *Error conditions:*
2101
 
2102
  - `operation_not_permitted` — if `pm` is `nullptr`.
2103
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
@@ -2110,16 +2744,15 @@ template <class Rep, class Period>
2110
  *Effects:* As if by `pm->try_lock_shared_for(rel_time)`.
2111
 
2112
  *Returns:* The value returned by the call to
2113
  `pm->try_lock_shared_for(rel_time)`.
2114
 
2115
- *Postconditions:* `owns == res`, where `res` is the value returned by
2116
- the call to `pm->try_lock_shared_for(rel_time)`.
2117
 
2118
  *Throws:* Any exception thrown by `pm->try_lock_shared_for(rel_time)`.
2119
- `system_error` when an exception is
2120
- required ([[thread.req.exception]]).
2121
 
2122
  *Error conditions:*
2123
 
2124
  - `operation_not_permitted` — if `pm` is `nullptr`.
2125
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
@@ -2128,20 +2761,20 @@ required ([[thread.req.exception]]).
2128
  void unlock();
2129
  ```
2130
 
2131
  *Effects:* As if by `pm->unlock_shared()`.
2132
 
2133
- *Postconditions:* `owns == false`.
2134
 
2135
  *Throws:* `system_error` when an exception is
2136
- required ([[thread.req.exception]]).
2137
 
2138
  *Error conditions:*
2139
 
2140
  - `operation_not_permitted` — if on entry `owns` is `false`.
2141
 
2142
- ##### `shared_lock` modifiers <a id="thread.lock.shared.mod">[[thread.lock.shared.mod]]</a>
2143
 
2144
  ``` cpp
2145
  void swap(shared_lock& sl) noexcept;
2146
  ```
2147
 
@@ -2151,20 +2784,20 @@ void swap(shared_lock& sl) noexcept;
2151
  mutex_type* release() noexcept;
2152
  ```
2153
 
2154
  *Returns:* The previous value of `pm`.
2155
 
2156
- *Postconditions:* `pm == nullptr` and `owns == false`.
2157
 
2158
  ``` cpp
2159
  template<class Mutex>
2160
  void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
2161
  ```
2162
 
2163
  *Effects:* As if by `x.swap(y)`.
2164
 
2165
- ##### `shared_lock` observers <a id="thread.lock.shared.obs">[[thread.lock.shared.obs]]</a>
2166
 
2167
  ``` cpp
2168
  bool owns_lock() const noexcept;
2169
  ```
2170
 
@@ -2186,48 +2819,47 @@ mutex_type* mutex() const noexcept;
2186
 
2187
  ``` cpp
2188
  template<class L1, class L2, class... L3> int try_lock(L1&, L2&, L3&...);
2189
  ```
2190
 
2191
- *Requires:* Each template parameter type shall meet the `Lockable`
2192
  requirements.
2193
 
2194
  [*Note 1*: The `unique_lock` class template meets these requirements
2195
  when suitably instantiated. — *end note*]
2196
 
2197
  *Effects:* Calls `try_lock()` for each argument in order beginning with
2198
  the first until all arguments have been processed or a call to
2199
  `try_lock()` fails, either by returning `false` or by throwing an
2200
- exception. If a call to `try_lock()` fails, `unlock()` shall be called
2201
- for all prior arguments and there shall be no further calls to
2202
- `try_lock()`.
2203
 
2204
  *Returns:* `-1` if all calls to `try_lock()` returned `true`, otherwise
2205
  a zero-based index value that indicates the argument for which
2206
  `try_lock()` returned `false`.
2207
 
2208
  ``` cpp
2209
  template<class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);
2210
  ```
2211
 
2212
- *Requires:* Each template parameter type shall meet the `Lockable`
2213
- requirements,
2214
 
2215
  [*Note 2*: The `unique_lock` class template meets these requirements
2216
  when suitably instantiated. — *end note*]
2217
 
2218
  *Effects:* All arguments are locked via a sequence of calls to `lock()`,
2219
- `try_lock()`, or `unlock()` on each argument. The sequence of calls
2220
- shall not result in deadlock, but is otherwise unspecified.
2221
 
2222
  [*Note 3*: A deadlock avoidance algorithm such as try-and-back-off must
2223
  be used, but the specific algorithm is not specified to avoid
2224
  over-constraining implementations. — *end note*]
2225
 
2226
- If a call to `lock()` or `try_lock()` throws an exception, `unlock()`
2227
- shall be called for any argument that had been locked by a call to
2228
- `lock()` or `try_lock()`.
2229
 
2230
  ### Call once <a id="thread.once">[[thread.once]]</a>
2231
 
2232
  #### Struct `once_flag` <a id="thread.once.onceflag">[[thread.once.onceflag]]</a>
2233
 
@@ -2247,57 +2879,49 @@ to initialize data without causing a data race or deadlock.
2247
 
2248
  ``` cpp
2249
  constexpr once_flag() noexcept;
2250
  ```
2251
 
2252
- *Effects:* Constructs an object of type `once_flag`.
2253
-
2254
  *Synchronization:* The construction of a `once_flag` object is not
2255
  synchronized.
2256
 
2257
- *Postconditions:* The object’s internal state is set to indicate to an
2258
  invocation of `call_once` with the object as its initial argument that
2259
  no function has been called.
2260
 
2261
  #### Function `call_once` <a id="thread.once.callonce">[[thread.once.callonce]]</a>
2262
 
2263
  ``` cpp
2264
  template<class Callable, class... Args>
2265
  void call_once(once_flag& flag, Callable&& func, Args&&... args);
2266
  ```
2267
 
2268
- *Requires:*
2269
-
2270
- ``` cpp
2271
- INVOKE(std::forward<Callable>(func), std::forward<Args>(args)...)
2272
- ```
2273
-
2274
- (see [[func.require]]) shall be a valid expression.
2275
 
2276
  *Effects:* An execution of `call_once` that does not call its `func` is
2277
  a *passive* execution. An execution of `call_once` that calls its `func`
2278
- is an *active* execution. An active execution shall call *INVOKE*(
2279
  std::forward\<Callable\>(func), std::forward\<Args\>(args)...). If such
2280
  a call to `func` throws an exception the execution is *exceptional*,
2281
- otherwise it is *returning*. An exceptional execution shall propagate
2282
- the exception to the caller of `call_once`. Among all executions of
2283
- `call_once` for any given `once_flag`: at most one shall be a returning
2284
- execution; if there is a returning execution, it shall be the last
2285
- active execution; and there are passive executions only if there is a
2286
- returning execution.
2287
 
2288
  [*Note 1*: Passive executions allow other threads to reliably observe
2289
  the results produced by the earlier returning execution. — *end note*]
2290
 
2291
  *Synchronization:* For any given `once_flag`: all active executions
2292
  occur in a total order; completion of an active execution synchronizes
2293
- with ([[intro.multithread]]) the start of the next one in this total
2294
  order; and the returning execution synchronizes with the return from all
2295
  passive executions.
2296
 
2297
  *Throws:* `system_error` when an exception is
2298
- required ([[thread.req.exception]]), or any exception thrown by `func`.
2299
 
2300
  [*Example 1*:
2301
 
2302
  ``` cpp
2303
  // global flag, regular function
@@ -2333,35 +2957,35 @@ public:
2333
 
2334
  Condition variables provide synchronization primitives used to block a
2335
  thread until notified by some other thread that some condition is met or
2336
  until a system time is reached. Class `condition_variable` provides a
2337
  condition variable that can only wait on an object of type
2338
- `unique_lock<mutex>`, allowing maximum efficiency on some platforms.
2339
  Class `condition_variable_any` provides a general condition variable
2340
  that can wait on objects of user-supplied lock types.
2341
 
2342
  Condition variables permit concurrent invocation of the `wait`,
2343
  `wait_for`, `wait_until`, `notify_one` and `notify_all` member
2344
  functions.
2345
 
2346
- The execution of `notify_one` and `notify_all` shall be atomic. The
2347
- execution of `wait`, `wait_for`, and `wait_until` shall be performed in
2348
  three atomic parts:
2349
 
2350
  1. the release of the mutex and entry into the waiting state;
2351
  2. the unblocking of the wait; and
2352
  3. the reacquisition of the lock.
2353
 
2354
- The implementation shall behave as if all executions of `notify_one`,
2355
  `notify_all`, and each part of the `wait`, `wait_for`, and `wait_until`
2356
  executions are executed in a single unspecified total order consistent
2357
  with the "happens before" order.
2358
 
2359
  Condition variable construction and destruction need not be
2360
  synchronized.
2361
 
2362
- ### Header `<condition_variable>` synopsis <a id="condition_variable.syn">[[condition_variable.syn]]</a>
2363
 
2364
  ``` cpp
2365
  namespace std {
2366
  class condition_variable;
2367
  class condition_variable_any;
@@ -2376,22 +3000,22 @@ namespace std {
2376
 
2377
  ``` cpp
2378
  void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
2379
  ```
2380
 
2381
- *Requires:* `lk` is locked by the calling thread and either
2382
 
2383
  - no other thread is waiting on `cond`, or
2384
  - `lk.mutex()` returns the same value for each of the lock arguments
2385
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
2386
  `wait_until`) threads.
2387
 
2388
  *Effects:* Transfers ownership of the lock associated with `lk` into
2389
  internal storage and schedules `cond` to be notified when the current
2390
  thread exits, after all objects of thread storage duration associated
2391
- with the current thread have been destroyed. This notification shall be
2392
- as if:
2393
 
2394
  ``` cpp
2395
  lk.unlock();
2396
  cond.notify_all();
2397
  ```
@@ -2399,11 +3023,11 @@ cond.notify_all();
2399
  *Synchronization:* The implied `lk.unlock()` call is sequenced after the
2400
  destruction of all objects with thread storage duration associated with
2401
  the current thread.
2402
 
2403
  [*Note 1*: The supplied lock will be held until the thread exits, and
2404
- care must be taken to ensure that this does not cause deadlock due to
2405
  lock ordering issues. After calling `notify_all_at_thread_exit` it is
2406
  recommended that the thread should be exited as soon as possible, and
2407
  that no blocking or time-consuming tasks are run on that
2408
  thread. — *end note*]
2409
 
@@ -2418,11 +3042,10 @@ this lock is not released and reacquired prior to calling
2418
 
2419
  ``` cpp
2420
  namespace std {
2421
  class condition_variable {
2422
  public:
2423
-
2424
  condition_variable();
2425
  ~condition_variable();
2426
 
2427
  condition_variable(const condition_variable&) = delete;
2428
  condition_variable& operator=(const condition_variable&) = delete;
@@ -2437,60 +3060,55 @@ namespace std {
2437
  const chrono::time_point<Clock, Duration>& abs_time);
2438
  template<class Clock, class Duration, class Predicate>
2439
  bool wait_until(unique_lock<mutex>& lock,
2440
  const chrono::time_point<Clock, Duration>& abs_time,
2441
  Predicate pred);
2442
-
2443
  template<class Rep, class Period>
2444
  cv_status wait_for(unique_lock<mutex>& lock,
2445
  const chrono::duration<Rep, Period>& rel_time);
2446
  template<class Rep, class Period, class Predicate>
2447
  bool wait_for(unique_lock<mutex>& lock,
2448
  const chrono::duration<Rep, Period>& rel_time,
2449
  Predicate pred);
2450
 
2451
- using native_handle_type = implementation-defined; // See~[thread.req.native]
2452
- native_handle_type native_handle(); // See~[thread.req.native]
2453
  };
2454
  }
2455
  ```
2456
 
2457
- The class `condition_variable` shall be a standard-layout class (Clause 
2458
- [[class]]).
2459
 
2460
  ``` cpp
2461
  condition_variable();
2462
  ```
2463
 
2464
- *Effects:* Constructs an object of type `condition_variable`.
2465
-
2466
  *Throws:* `system_error` when an exception is
2467
- required ([[thread.req.exception]]).
2468
 
2469
  *Error conditions:*
2470
 
2471
  - `resource_unavailable_try_again` — if some non-memory resource
2472
  limitation prevents initialization.
2473
 
2474
  ``` cpp
2475
  ~condition_variable();
2476
  ```
2477
 
2478
- *Requires:* There shall be no thread blocked on `*this`.
2479
 
2480
- [*Note 1*: That is, all threads shall have been notified; they may
2481
  subsequently block on the lock specified in the wait. This relaxes the
2482
  usual rules, which would have required all wait calls to happen before
2483
- destruction. Only the notification to unblock the wait must happen
2484
- before destruction. The user must take care to ensure that no threads
2485
  wait on `*this` once the destructor has been started, especially when
2486
  the waiting threads are calling the wait functions in a loop or using
2487
  the overloads of `wait`, `wait_for`, or `wait_until` that take a
2488
  predicate. — *end note*]
2489
 
2490
- *Effects:* Destroys the object.
2491
-
2492
  ``` cpp
2493
  void notify_one() noexcept;
2494
  ```
2495
 
2496
  *Effects:* If any threads are blocked waiting for `*this`, unblocks one
@@ -2504,12 +3122,12 @@ void notify_all() noexcept;
2504
 
2505
  ``` cpp
2506
  void wait(unique_lock<mutex>& lock);
2507
  ```
2508
 
2509
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
2510
- the calling thread, and either
2511
 
2512
  - no other thread is waiting on this `condition_variable` object or
2513
  - `lock.mutex()` returns the same value for each of the `lock` arguments
2514
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
2515
  `wait_until`) threads.
@@ -2521,27 +3139,27 @@ the calling thread, and either
2521
  then returns.
2522
  - The function will unblock when signaled by a call to `notify_one()` or
2523
  a call to `notify_all()`, or spuriously.
2524
 
2525
  *Remarks:* If the function fails to meet the postcondition,
2526
- `terminate()` shall be called ([[except.terminate]]).
2527
 
2528
  [*Note 2*: This can happen if the re-locking of the mutex throws an
2529
  exception. — *end note*]
2530
 
2531
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
2532
- locked by the calling thread.
2533
 
2534
  *Throws:* Nothing.
2535
 
2536
  ``` cpp
2537
  template<class Predicate>
2538
  void wait(unique_lock<mutex>& lock, Predicate pred);
2539
  ```
2540
 
2541
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
2542
- the calling thread, and either
2543
 
2544
  - no other thread is waiting on this `condition_variable` object or
2545
  - `lock.mutex()` returns the same value for each of the `lock` arguments
2546
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
2547
  `wait_until`) threads.
@@ -2552,28 +3170,28 @@ the calling thread, and either
2552
  while (!pred())
2553
  wait(lock);
2554
  ```
2555
 
2556
  *Remarks:* If the function fails to meet the postcondition,
2557
- `terminate()` shall be called ([[except.terminate]]).
2558
 
2559
  [*Note 3*: This can happen if the re-locking of the mutex throws an
2560
  exception. — *end note*]
2561
 
2562
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
2563
- locked by the calling thread.
2564
 
2565
  *Throws:* Any exception thrown by `pred`.
2566
 
2567
  ``` cpp
2568
  template<class Clock, class Duration>
2569
  cv_status wait_until(unique_lock<mutex>& lock,
2570
  const chrono::time_point<Clock, Duration>& abs_time);
2571
  ```
2572
 
2573
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
2574
- the calling thread, and either
2575
 
2576
  - no other thread is waiting on this `condition_variable` object or
2577
  - `lock.mutex()` returns the same value for each of the `lock` arguments
2578
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
2579
  `wait_until`) threads.
@@ -2583,38 +3201,37 @@ the calling thread, and either
2583
  - Atomically calls `lock.unlock()` and blocks on `*this`.
2584
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock),
2585
  then returns.
2586
  - The function will unblock when signaled by a call to `notify_one()`, a
2587
  call to `notify_all()`, expiration of the absolute
2588
- timeout ([[thread.req.timing]]) specified by `abs_time`, or
2589
- spuriously.
2590
- - If the function exits via an exception, `lock.lock()` shall be called
2591
- prior to exiting the function.
2592
 
2593
  *Remarks:* If the function fails to meet the postcondition,
2594
- `terminate()` shall be called ([[except.terminate]]).
2595
 
2596
  [*Note 4*: This can happen if the re-locking of the mutex throws an
2597
  exception. — *end note*]
2598
 
2599
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
2600
- locked by the calling thread.
2601
 
2602
  *Returns:* `cv_status::timeout` if the absolute
2603
- timeout ([[thread.req.timing]]) specified by `abs_time` expired,
2604
- otherwise `cv_status::no_timeout`.
2605
 
2606
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
2607
 
2608
  ``` cpp
2609
  template<class Rep, class Period>
2610
  cv_status wait_for(unique_lock<mutex>& lock,
2611
  const chrono::duration<Rep, Period>& rel_time);
2612
  ```
2613
 
2614
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
2615
- the calling thread, and either
2616
 
2617
  - no other thread is waiting on this `condition_variable` object or
2618
  - `lock.mutex()` returns the same value for each of the `lock` arguments
2619
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
2620
  `wait_until`) threads.
@@ -2624,33 +3241,33 @@ the calling thread, and either
2624
  ``` cpp
2625
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
2626
  ```
2627
 
2628
  *Returns:* `cv_status::timeout` if the relative
2629
- timeout ([[thread.req.timing]]) specified by `rel_time` expired,
2630
- otherwise `cv_status::no_timeout`.
2631
 
2632
  *Remarks:* If the function fails to meet the postcondition,
2633
- `terminate()` shall be called ([[except.terminate]]).
2634
 
2635
  [*Note 5*: This can happen if the re-locking of the mutex throws an
2636
  exception. — *end note*]
2637
 
2638
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
2639
- locked by the calling thread.
2640
 
2641
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
2642
 
2643
  ``` cpp
2644
  template<class Clock, class Duration, class Predicate>
2645
  bool wait_until(unique_lock<mutex>& lock,
2646
  const chrono::time_point<Clock, Duration>& abs_time,
2647
  Predicate pred);
2648
  ```
2649
 
2650
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
2651
- the calling thread, and either
2652
 
2653
  - no other thread is waiting on this `condition_variable` object or
2654
  - `lock.mutex()` returns the same value for each of the `lock` arguments
2655
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
2656
  `wait_until`) threads.
@@ -2663,34 +3280,34 @@ while (!pred())
2663
  return pred();
2664
  return true;
2665
  ```
2666
 
2667
  *Remarks:* If the function fails to meet the postcondition,
2668
- `terminate()` shall be called ([[except.terminate]]).
2669
 
2670
  [*Note 6*: This can happen if the re-locking of the mutex throws an
2671
  exception. — *end note*]
2672
 
2673
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
2674
- locked by the calling thread.
2675
 
2676
  [*Note 7*: The returned value indicates whether the predicate evaluated
2677
  to `true` regardless of whether the timeout was
2678
  triggered. — *end note*]
2679
 
2680
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]) or any
2681
  exception thrown by `pred`.
2682
 
2683
  ``` cpp
2684
  template<class Rep, class Period, class Predicate>
2685
  bool wait_for(unique_lock<mutex>& lock,
2686
  const chrono::duration<Rep, Period>& rel_time,
2687
  Predicate pred);
2688
  ```
2689
 
2690
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
2691
- the calling thread, and either
2692
 
2693
  - no other thread is waiting on this `condition_variable` object or
2694
  - `lock.mutex()` returns the same value for each of the `lock` arguments
2695
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
2696
  `wait_until`) threads.
@@ -2703,34 +3320,34 @@ return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred))
2703
 
2704
  [*Note 8*: There is no blocking if `pred()` is initially `true`, even
2705
  if the timeout has already expired. — *end note*]
2706
 
2707
  *Remarks:* If the function fails to meet the postcondition,
2708
- `terminate()` shall be called ([[except.terminate]]).
2709
 
2710
  [*Note 9*: This can happen if the re-locking of the mutex throws an
2711
  exception. — *end note*]
2712
 
2713
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
2714
- locked by the calling thread.
2715
 
2716
  [*Note 10*: The returned value indicates whether the predicate
2717
  evaluates to `true` regardless of whether the timeout was
2718
  triggered. — *end note*]
2719
 
2720
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]) or any
2721
  exception thrown by `pred`.
2722
 
2723
  ### Class `condition_variable_any` <a id="thread.condition.condvarany">[[thread.condition.condvarany]]</a>
2724
 
2725
- A `Lock` type shall meet the `BasicLockable` requirements (
2726
- [[thread.req.lockable.basic]]).
2727
 
2728
  [*Note 1*: All of the standard mutex types meet this requirement. If a
2729
  `Lock` type other than one of the standard mutex types or a
2730
  `unique_lock` wrapper for a standard mutex type is used with
2731
- `condition_variable_any`, the user must ensure that any necessary
2732
  synchronization is in place with respect to the predicate associated
2733
  with the `condition_variable_any` instance. — *end note*]
2734
 
2735
  ``` cpp
2736
  namespace std {
@@ -2742,10 +3359,12 @@ namespace std {
2742
  condition_variable_any(const condition_variable_any&) = delete;
2743
  condition_variable_any& operator=(const condition_variable_any&) = delete;
2744
 
2745
  void notify_one() noexcept;
2746
  void notify_all() noexcept;
 
 
2747
  template<class Lock>
2748
  void wait(Lock& lock);
2749
  template<class Lock, class Predicate>
2750
  void wait(Lock& lock, Predicate pred);
2751
 
@@ -2755,24 +3374,31 @@ namespace std {
2755
  bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time,
2756
  Predicate pred);
2757
  template<class Lock, class Rep, class Period>
2758
  cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
2759
  template<class Lock, class Rep, class Period, class Predicate>
2760
- bool wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time,
2761
- Predicate pred);
 
 
 
 
 
 
 
 
 
2762
  };
2763
  }
2764
  ```
2765
 
2766
  ``` cpp
2767
  condition_variable_any();
2768
  ```
2769
 
2770
- *Effects:* Constructs an object of type `condition_variable_any`.
2771
-
2772
  *Throws:* `bad_alloc` or `system_error` when an exception is
2773
- required ([[thread.req.exception]]).
2774
 
2775
  *Error conditions:*
2776
 
2777
  - `resource_unavailable_try_again` — if some non-memory resource
2778
  limitation prevents initialization.
@@ -2781,24 +3407,22 @@ required ([[thread.req.exception]]).
2781
 
2782
  ``` cpp
2783
  ~condition_variable_any();
2784
  ```
2785
 
2786
- *Requires:* There shall be no thread blocked on `*this`.
2787
 
2788
- [*Note 1*: That is, all threads shall have been notified; they may
2789
  subsequently block on the lock specified in the wait. This relaxes the
2790
  usual rules, which would have required all wait calls to happen before
2791
- destruction. Only the notification to unblock the wait must happen
2792
- before destruction. The user must take care to ensure that no threads
2793
  wait on `*this` once the destructor has been started, especially when
2794
  the waiting threads are calling the wait functions in a loop or using
2795
  the overloads of `wait`, `wait_for`, or `wait_until` that take a
2796
  predicate. — *end note*]
2797
 
2798
- *Effects:* Destroys the object.
2799
-
2800
  ``` cpp
2801
  void notify_one() noexcept;
2802
  ```
2803
 
2804
  *Effects:* If any threads are blocked waiting for `*this`, unblocks one
@@ -2808,34 +3432,32 @@ of those threads.
2808
  void notify_all() noexcept;
2809
  ```
2810
 
2811
  *Effects:* Unblocks all threads that are blocked waiting for `*this`.
2812
 
 
 
2813
  ``` cpp
2814
  template<class Lock>
2815
  void wait(Lock& lock);
2816
  ```
2817
 
2818
- [*Note 2*: If any of the `wait` functions exits via an exception, it is
2819
- unspecified whether the `Lock` is held. One can use a `Lock` type that
2820
- allows to query that, such as the `unique_lock` wrapper. — *end note*]
2821
-
2822
  *Effects:*
2823
 
2824
  - Atomically calls `lock.unlock()` and blocks on `*this`.
2825
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock)
2826
  and returns.
2827
  - The function will unblock when signaled by a call to `notify_one()`, a
2828
  call to `notify_all()`, or spuriously.
2829
 
2830
  *Remarks:* If the function fails to meet the postcondition,
2831
- `terminate()` shall be called ([[except.terminate]]).
2832
 
2833
- [*Note 3*: This can happen if the re-locking of the mutex throws an
2834
  exception. — *end note*]
2835
 
2836
- *Postconditions:* `lock` is locked by the calling thread.
2837
 
2838
  *Throws:* Nothing.
2839
 
2840
  ``` cpp
2841
  template<class Lock, class Predicate>
@@ -2859,28 +3481,27 @@ template <class Lock, class Clock, class Duration>
2859
  - Atomically calls `lock.unlock()` and blocks on `*this`.
2860
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock)
2861
  and returns.
2862
  - The function will unblock when signaled by a call to `notify_one()`, a
2863
  call to `notify_all()`, expiration of the absolute
2864
- timeout ([[thread.req.timing]]) specified by `abs_time`, or
2865
- spuriously.
2866
- - If the function exits via an exception, `lock.lock()` shall be called
2867
- prior to exiting the function.
2868
 
2869
  *Remarks:* If the function fails to meet the postcondition,
2870
- `terminate()` shall be called ([[except.terminate]]).
2871
 
2872
- [*Note 4*: This can happen if the re-locking of the mutex throws an
2873
  exception. — *end note*]
2874
 
2875
- *Postconditions:* `lock` is locked by the calling thread.
2876
 
2877
  *Returns:* `cv_status::timeout` if the absolute
2878
- timeout ([[thread.req.timing]]) specified by `abs_time` expired,
2879
- otherwise `cv_status::no_timeout`.
2880
 
2881
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
2882
 
2883
  ``` cpp
2884
  template<class Lock, class Rep, class Period>
2885
  cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
2886
  ```
@@ -2890,22 +3511,22 @@ template <class Lock, class Rep, class Period>
2890
  ``` cpp
2891
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
2892
  ```
2893
 
2894
  *Returns:* `cv_status::timeout` if the relative
2895
- timeout ([[thread.req.timing]]) specified by `rel_time` expired,
2896
- otherwise `cv_status::no_timeout`.
2897
 
2898
  *Remarks:* If the function fails to meet the postcondition,
2899
- `terminate()` shall be called ([[except.terminate]]).
2900
 
2901
- [*Note 5*: This can happen if the re-locking of the mutex throws an
2902
  exception. — *end note*]
2903
 
2904
- *Postconditions:* `lock` is locked by the calling thread.
2905
 
2906
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
2907
 
2908
  ``` cpp
2909
  template<class Lock, class Clock, class Duration, class Predicate>
2910
  bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
2911
  ```
@@ -2917,14 +3538,14 @@ while (!pred())
2917
  if (wait_until(lock, abs_time) == cv_status::timeout)
2918
  return pred();
2919
  return true;
2920
  ```
2921
 
2922
- [*Note 6*: There is no blocking if `pred()` is initially `true`, or if
2923
  the timeout has already expired. — *end note*]
2924
 
2925
- [*Note 7*: The returned value indicates whether the predicate evaluates
2926
  to `true` regardless of whether the timeout was
2927
  triggered. — *end note*]
2928
 
2929
  ``` cpp
2930
  template<class Lock, class Rep, class Period, class Predicate>
@@ -2935,10 +3556,584 @@ template <class Lock, class Rep, class Period, class Predicate>
2935
 
2936
  ``` cpp
2937
  return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));
2938
  ```
2939
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2940
  ## Futures <a id="futures">[[futures]]</a>
2941
 
2942
  ### Overview <a id="futures.overview">[[futures.overview]]</a>
2943
 
2944
  [[futures]] describes components that a C++ program can use to retrieve
@@ -3003,23 +4198,20 @@ namespace std {
3003
  class packaged_task<R(ArgTypes...)>;
3004
 
3005
  template<class R, class... ArgTypes>
3006
  void swap(packaged_task<R(ArgTypes...)>&, packaged_task<R(ArgTypes...)>&) noexcept;
3007
 
3008
- template <class R, class Alloc>
3009
- struct uses_allocator<packaged_task<R>, Alloc>;
3010
-
3011
  template<class F, class... Args>
3012
- future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
3013
  async(F&& f, Args&&... args);
3014
  template<class F, class... Args>
3015
- future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
3016
  async(launch policy, F&& f, Args&&... args);
3017
  }
3018
  ```
3019
 
3020
- The `enum` type `launch` is a bitmask type ([[bitmask.types]]) with
3021
  elements `launch::async` and `launch::deferred`.
3022
 
3023
  [*Note 1*: Implementations can provide bitmasks to specify restrictions
3024
  on task interaction by functions launched by `async()` applicable to a
3025
  corresponding subset of available launch policies. Implementations can
@@ -3032,16 +4224,16 @@ The enum values of `future_errc` are distinct and not zero.
3032
 
3033
  ``` cpp
3034
  const error_category& future_category() noexcept;
3035
  ```
3036
 
3037
- *Returns:*  A reference to an object of a type derived from class
3038
  `error_category`.
3039
 
3040
  The object’s `default_error_condition` and equivalent virtual functions
3041
  shall behave as specified for the class `error_category`. The object’s
3042
- `name` virtual function shall return a pointer to the string `"future"`.
3043
 
3044
  ``` cpp
3045
  error_code make_error_code(future_errc e) noexcept;
3046
  ```
3047
 
@@ -3051,32 +4243,32 @@ error_code make_error_code(future_errc e) noexcept;
3051
  error_condition make_error_condition(future_errc e) noexcept;
3052
  ```
3053
 
3054
  *Returns:* `error_condition(static_cast<int>(e), future_category())`.
3055
 
3056
- ### Class `future_error` <a id="futures.future_error">[[futures.future_error]]</a>
3057
 
3058
  ``` cpp
3059
  namespace std {
3060
  class future_error : public logic_error {
3061
  public:
3062
  explicit future_error(future_errc e);
3063
 
3064
  const error_code& code() const noexcept;
3065
  const char* what() const noexcept;
 
3066
  private:
3067
  error_code ec_; // exposition only
3068
  };
3069
  }
3070
  ```
3071
 
3072
  ``` cpp
3073
  explicit future_error(future_errc e);
3074
  ```
3075
 
3076
- *Effects:* Constructs an object of class `future_error` and initializes
3077
- `ec_` with `make_error_code(e)`.
3078
 
3079
  ``` cpp
3080
  const error_code& code() const noexcept;
3081
  ```
3082
 
@@ -3088,12 +4280,12 @@ const char* what() const noexcept;
3088
 
3089
  *Returns:* An NTBS incorporating `code().message()`.
3090
 
3091
  ### Shared state <a id="futures.state">[[futures.state]]</a>
3092
 
3093
- Many of the classes introduced in this subclause use some state to
3094
- communicate results. This *shared state* consists of some state
3095
  information and some (possibly not yet evaluated) *result*, which can be
3096
  a (possibly void) value or an exception.
3097
 
3098
  [*Note 1*: Futures, promises, and tasks defined in this clause
3099
  reference such shared state. — *end note*]
@@ -3104,11 +4296,11 @@ compute that result, as used by `async` when `policy` is
3104
 
3105
  An *asynchronous return object* is an object that reads results from a
3106
  shared state. A *waiting function* of an asynchronous return object is
3107
  one that potentially blocks to wait for the shared state to be made
3108
  ready. If a waiting function can return before the state is made ready
3109
- because of a timeout ([[thread.req.lockable]]), then it is a *timed
3110
  waiting function*, otherwise it is a *non-timed waiting function*.
3111
 
3112
  An *asynchronous provider* is an object that provides a result to a
3113
  shared state. The result of a shared state is set by respective
3114
  functions on the asynchronous provider.
@@ -3151,30 +4343,29 @@ A shared state is *ready* only if it holds a value or an exception ready
3151
  for retrieval. Waiting for a shared state to become ready may invoke
3152
  code to compute the result on the waiting thread if so specified in the
3153
  description of the class or function that creates the state object.
3154
 
3155
  Calls to functions that successfully set the stored result of a shared
3156
- state synchronize with ([[intro.multithread]]) calls to functions
3157
  successfully detecting the ready state resulting from that setting. The
3158
  storage of the result (whether normal or exceptional) into the shared
3159
- state synchronizes with ([[intro.multithread]]) the successful return
3160
- from a call to a waiting function on the shared state.
3161
 
3162
  Some functions (e.g., `promise::set_value_at_thread_exit`) delay making
3163
  the shared state ready until the calling thread exits. The destruction
3164
- of each of that thread’s objects with thread storage duration (
3165
- [[basic.stc.thread]]) is sequenced before making that shared state
3166
- ready.
3167
 
3168
- Access to the result of the same shared state may conflict (
3169
- [[intro.multithread]]).
3170
 
3171
  [*Note 4*: This explicitly specifies that the result of the shared
3172
  state is visible in the objects that reference this state in the sense
3173
- of data race avoidance ([[res.on.data.races]]). For example, concurrent
3174
- accesses through references returned by `shared_future::get()` (
3175
- [[futures.shared_future]]) must either use read-only operations or
3176
  provide additional synchronization. — *end note*]
3177
 
3178
  ### Class template `promise` <a id="futures.promise">[[futures.promise]]</a>
3179
 
3180
  ``` cpp
@@ -3184,16 +4375,16 @@ namespace std {
3184
  public:
3185
  promise();
3186
  template<class Allocator>
3187
  promise(allocator_arg_t, const Allocator& a);
3188
  promise(promise&& rhs) noexcept;
3189
- promise(const promise& rhs) = delete;
3190
  ~promise();
3191
 
3192
  // assignment
3193
  promise& operator=(promise&& rhs) noexcept;
3194
- promise& operator=(const promise& rhs) = delete;
3195
  void swap(promise& other) noexcept;
3196
 
3197
  // retrieving the result
3198
  future<R> get_future();
3199
 
@@ -3203,18 +4394,20 @@ namespace std {
3203
 
3204
  // setting the result with deferred notification
3205
  void set_value_at_thread_exit(see below);
3206
  void set_exception_at_thread_exit(exception_ptr p);
3207
  };
 
3208
  template<class R>
3209
  void swap(promise<R>& x, promise<R>& y) noexcept;
 
3210
  template<class R, class Alloc>
3211
  struct uses_allocator<promise<R>, Alloc>;
3212
  }
3213
  ```
3214
 
3215
- The implementation shall provide the template `promise` and two
3216
  specializations, `promise<R&>` and `promise<{}void>`. These differ only
3217
  in the argument type of the member functions `set_value` and
3218
  `set_value_at_thread_exit`, as set out in their descriptions, below.
3219
 
3220
  The `set_value`, `set_exception`, `set_value_at_thread_exit`, and
@@ -3226,62 +4419,69 @@ the promise object.
3226
  template<class R, class Alloc>
3227
  struct uses_allocator<promise<R>, Alloc>
3228
  : true_type { };
3229
  ```
3230
 
3231
- *Requires:* `Alloc` shall be an Allocator ([[allocator.requirements]]).
 
3232
 
3233
  ``` cpp
3234
  promise();
3235
  template<class Allocator>
3236
  promise(allocator_arg_t, const Allocator& a);
3237
  ```
3238
 
3239
- *Effects:* constructs a `promise` object and a shared state. The second
3240
- constructor uses the allocator `a` to allocate memory for the shared
3241
- state.
3242
 
3243
  ``` cpp
3244
  promise(promise&& rhs) noexcept;
3245
  ```
3246
 
3247
- *Effects:* constructs a new `promise` object and transfers ownership of
3248
- the shared state of `rhs` (if any) to the newly-constructed object.
3249
 
3250
- *Postconditions:* `rhs` has no shared state.
3251
 
3252
  ``` cpp
3253
  ~promise();
3254
  ```
3255
 
3256
- *Effects:* Abandons any shared state ([[futures.state]]).
3257
 
3258
  ``` cpp
3259
  promise& operator=(promise&& rhs) noexcept;
3260
  ```
3261
 
3262
- *Effects:* Abandons any shared state ([[futures.state]]) and then as if
3263
  `promise(std::move(rhs)).swap(*this)`.
3264
 
3265
  *Returns:* `*this`.
3266
 
3267
  ``` cpp
3268
  void swap(promise& other) noexcept;
3269
  ```
3270
 
3271
  *Effects:* Exchanges the shared state of `*this` and `other`.
3272
 
3273
- *Postconditions:* `*this` has the shared state (if any) that `other` had
3274
- prior to the call to `swap`. `other` has the shared state (if any) that
3275
  `*this` had prior to the call to `swap`.
3276
 
3277
  ``` cpp
3278
  future<R> get_future();
3279
  ```
3280
 
3281
  *Returns:* A `future<R>` object with the same shared state as `*this`.
3282
 
 
 
 
 
 
 
 
3283
  *Throws:* `future_error` if `*this` has no shared state or if
3284
  `get_future` has already been called on a `promise` with the same shared
3285
  state as `*this`.
3286
 
3287
  *Error conditions:*
@@ -3296,11 +4496,11 @@ void promise::set_value(R&& r);
3296
  void promise<R&>::set_value(R& r);
3297
  void promise<void>::set_value();
3298
  ```
3299
 
3300
  *Effects:* Atomically stores the value `r` in the shared state and makes
3301
- that state ready ([[futures.state]]).
3302
 
3303
  *Throws:*
3304
 
3305
  - `future_error` if its shared state already has a stored value or
3306
  exception, or
@@ -3317,14 +4517,14 @@ that state ready ([[futures.state]]).
3317
 
3318
  ``` cpp
3319
  void set_exception(exception_ptr p);
3320
  ```
3321
 
3322
- *Requires:* `p` is not null.
3323
 
3324
  *Effects:* Atomically stores the exception pointer `p` in the shared
3325
- state and makes that state ready ([[futures.state]]).
3326
 
3327
  *Throws:* `future_error` if its shared state already has a stored value
3328
  or exception.
3329
 
3330
  *Error conditions:*
@@ -3362,11 +4562,11 @@ associated with the current thread have been destroyed.
3362
 
3363
  ``` cpp
3364
  void set_exception_at_thread_exit(exception_ptr p);
3365
  ```
3366
 
3367
- *Requires:* `p` is not null.
3368
 
3369
  *Effects:* Stores the exception pointer `p` in the shared state without
3370
  making that state ready immediately. Schedules that state to be made
3371
  ready when the current thread exits, after all objects of thread storage
3372
  duration associated with the current thread have been destroyed.
@@ -3384,21 +4584,20 @@ template <class R>
3384
  void swap(promise<R>& x, promise<R>& y) noexcept;
3385
  ```
3386
 
3387
  *Effects:* As if by `x.swap(y)`.
3388
 
3389
- ### Class template `future` <a id="futures.unique_future">[[futures.unique_future]]</a>
3390
 
3391
  The class template `future` defines a type for asynchronous return
3392
  objects which do not share their shared state with other asynchronous
3393
  return objects. A default-constructed `future` object has no shared
3394
  state. A `future` object with shared state can be created by functions
3395
- on asynchronous providers ([[futures.state]]) or by the move
3396
- constructor and shares its shared state with the original asynchronous
3397
- provider. The result (value or exception) of a `future` object can be
3398
- set by calling a respective function on an object that shares the same
3399
- shared state.
3400
 
3401
  [*Note 1*: Member functions of `future` do not synchronize with
3402
  themselves or with member functions of `shared_future`. — *end note*]
3403
 
3404
  The effect of calling any member function other than the destructor, the
@@ -3406,24 +4605,24 @@ move-assignment operator, `share`, or `valid` on a `future` object for
3406
  which `valid() == false` is undefined.
3407
 
3408
  [*Note 2*: It is valid to move from a future object for which
3409
  `valid() == false`. — *end note*]
3410
 
3411
- [*Note 3*: Implementations are encouraged to detect this case and throw
3412
- an object of type `future_error` with an error condition of
3413
  `future_errc::no_state`. — *end note*]
3414
 
3415
  ``` cpp
3416
  namespace std {
3417
  template<class R>
3418
  class future {
3419
  public:
3420
  future() noexcept;
3421
  future(future&&) noexcept;
3422
- future(const future& rhs) = delete;
3423
  ~future();
3424
- future& operator=(const future& rhs) = delete;
3425
  future& operator=(future&&) noexcept;
3426
  shared_future<R> share() noexcept;
3427
 
3428
  // retrieving the value
3429
  see below get();
@@ -3438,32 +4637,31 @@ namespace std {
3438
  future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
3439
  };
3440
  }
3441
  ```
3442
 
3443
- The implementation shall provide the template `future` and two
3444
  specializations, `future<R&>` and `future<{}void>`. These differ only in
3445
  the return type and return value of the member function `get`, as set
3446
  out in its description, below.
3447
 
3448
  ``` cpp
3449
  future() noexcept;
3450
  ```
3451
 
3452
- *Effects:* Constructs an *empty* `future` object that does not refer to
3453
- a shared state.
3454
 
3455
- *Postconditions:* `valid() == false`.
3456
 
3457
  ``` cpp
3458
  future(future&& rhs) noexcept;
3459
  ```
3460
 
3461
  *Effects:* Move constructs a `future` object that refers to the shared
3462
  state that was originally referred to by `rhs` (if any).
3463
 
3464
- *Postconditions:*
3465
 
3466
  - `valid()` returns the same value as `rhs.valid()` prior to the
3467
  constructor invocation.
3468
  - `rhs.valid() == false`.
3469
 
@@ -3471,23 +4669,23 @@ state that was originally referred to by `rhs` (if any).
3471
  ~future();
3472
  ```
3473
 
3474
  *Effects:*
3475
 
3476
- - Releases any shared state ([[futures.state]]);
3477
  - destroys `*this`.
3478
 
3479
  ``` cpp
3480
  future& operator=(future&& rhs) noexcept;
3481
  ```
3482
 
3483
  *Effects:*
3484
 
3485
- - Releases any shared state ([[futures.state]]).
3486
  - move assigns the contents of `rhs` to `*this`.
3487
 
3488
- *Postconditions:*
3489
 
3490
  - `valid()` returns the same value as `rhs.valid()` prior to the
3491
  assignment.
3492
  - `rhs.valid() == false`.
3493
 
@@ -3495,11 +4693,11 @@ future& operator=(future&& rhs) noexcept;
3495
  shared_future<R> share() noexcept;
3496
  ```
3497
 
3498
  *Returns:* `shared_future<R>(std::move(*this))`.
3499
 
3500
- *Postconditions:* `valid() == false`.
3501
 
3502
  ``` cpp
3503
  R future::get();
3504
  R& future<R&>::get();
3505
  void future<void>::get();
@@ -3511,24 +4709,24 @@ member function `get`. — *end note*]
3511
 
3512
  *Effects:*
3513
 
3514
  - `wait()`s until the shared state is ready, then retrieves the value
3515
  stored in the shared state;
3516
- - releases any shared state ([[futures.state]]).
3517
 
3518
  *Returns:*
3519
 
3520
  - `future::get()` returns the value `v` stored in the object’s shared
3521
  state as `std::move(v)`.
3522
  - `future<R&>::get()` returns the reference stored as value in the
3523
  object’s shared state.
3524
  - `future<void>::get()` returns nothing.
3525
 
3526
- *Throws:* the stored exception, if an exception was stored in the shared
3527
  state.
3528
 
3529
- *Postconditions:* `valid() == false`.
3530
 
3531
  ``` cpp
3532
  bool valid() const noexcept;
3533
  ```
3534
 
@@ -3544,57 +4742,57 @@ void wait() const;
3544
  template<class Rep, class Period>
3545
  future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
3546
  ```
3547
 
3548
  *Effects:* None if the shared state contains a deferred
3549
- function ([[futures.async]]), otherwise blocks until the shared state
3550
- is ready or until the relative timeout ([[thread.req.timing]])
3551
- specified by `rel_time` has expired.
3552
 
3553
  *Returns:*
3554
 
3555
  - `future_status::deferred` if the shared state contains a deferred
3556
  function.
3557
  - `future_status::ready` if the shared state is ready.
3558
  - `future_status::timeout` if the function is returning because the
3559
- relative timeout ([[thread.req.timing]]) specified by `rel_time` has
3560
  expired.
3561
 
3562
- *Throws:* timeout-related exceptions ([[thread.req.timing]]).
3563
 
3564
  ``` cpp
3565
  template<class Clock, class Duration>
3566
  future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
3567
  ```
3568
 
3569
  *Effects:* None if the shared state contains a deferred
3570
- function ([[futures.async]]), otherwise blocks until the shared state
3571
- is ready or until the absolute timeout ([[thread.req.timing]])
3572
- specified by `abs_time` has expired.
3573
 
3574
  *Returns:*
3575
 
3576
  - `future_status::deferred` if the shared state contains a deferred
3577
  function.
3578
  - `future_status::ready` if the shared state is ready.
3579
  - `future_status::timeout` if the function is returning because the
3580
- absolute timeout ([[thread.req.timing]]) specified by `abs_time` has
3581
  expired.
3582
 
3583
- *Throws:* timeout-related exceptions ([[thread.req.timing]]).
3584
 
3585
- ### Class template `shared_future` <a id="futures.shared_future">[[futures.shared_future]]</a>
3586
 
3587
  The class template `shared_future` defines a type for asynchronous
3588
  return objects which may share their shared state with other
3589
  asynchronous return objects. A default-constructed `shared_future`
3590
  object has no shared state. A `shared_future` object with shared state
3591
  can be created by conversion from a `future` object and shares its
3592
- shared state with the original asynchronous provider (
3593
- [[futures.state]]) of the shared state. The result (value or exception)
3594
- of a `shared_future` object can be set by calling a respective function
3595
- on an object that shares the same shared state.
3596
 
3597
  [*Note 1*: Member functions of `shared_future` do not synchronize with
3598
  themselves, but they synchronize with the shared state. — *end note*]
3599
 
3600
  The effect of calling any member function other than the destructor, the
@@ -3602,12 +4800,12 @@ move-assignment operator, the copy-assignment operator, or `valid()` on
3602
  a `shared_future` object for which `valid() == false` is undefined.
3603
 
3604
  [*Note 2*: It is valid to copy or move from a `shared_future` object
3605
  for which `valid()` is `false`. — *end note*]
3606
 
3607
- [*Note 3*: Implementations are encouraged to detect this case and throw
3608
- an object of type `future_error` with an error condition of
3609
  `future_errc::no_state`. — *end note*]
3610
 
3611
  ``` cpp
3612
  namespace std {
3613
  template<class R>
@@ -3634,42 +4832,40 @@ namespace std {
3634
  future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
3635
  };
3636
  }
3637
  ```
3638
 
3639
- The implementation shall provide the template `shared_future` and two
3640
  specializations, `shared_future<R&>` and `shared_future<void>`. These
3641
  differ only in the return type and return value of the member function
3642
  `get`, as set out in its description, below.
3643
 
3644
  ``` cpp
3645
  shared_future() noexcept;
3646
  ```
3647
 
3648
- *Effects:* Constructs an *empty* `shared_future` object that does not
3649
- refer to a shared state.
3650
 
3651
- *Postconditions:* `valid() == false`.
3652
 
3653
  ``` cpp
3654
  shared_future(const shared_future& rhs) noexcept;
3655
  ```
3656
 
3657
- *Effects:* Constructs a `shared_future` object that refers to the same
3658
- shared state as `rhs` (if any).
3659
 
3660
- *Postconditions:* `valid()` returns the same value as `rhs.valid()`.
3661
 
3662
  ``` cpp
3663
  shared_future(future<R>&& rhs) noexcept;
3664
  shared_future(shared_future&& rhs) noexcept;
3665
  ```
3666
 
3667
  *Effects:* Move constructs a `shared_future` object that refers to the
3668
  shared state that was originally referred to by `rhs` (if any).
3669
 
3670
- *Postconditions:*
3671
 
3672
  - `valid()` returns the same value as `rhs.valid()` returned prior to
3673
  the constructor invocation.
3674
  - `rhs.valid() == false`.
3675
 
@@ -3677,23 +4873,23 @@ shared state that was originally referred to by `rhs` (if any).
3677
  ~shared_future();
3678
  ```
3679
 
3680
  *Effects:*
3681
 
3682
- - Releases any shared state ([[futures.state]]);
3683
  - destroys `*this`.
3684
 
3685
  ``` cpp
3686
  shared_future& operator=(shared_future&& rhs) noexcept;
3687
  ```
3688
 
3689
  *Effects:*
3690
 
3691
- - Releases any shared state ([[futures.state]]);
3692
  - move assigns the contents of `rhs` to `*this`.
3693
 
3694
- *Postconditions:*
3695
 
3696
  - `valid()` returns the same value as `rhs.valid()` returned prior to
3697
  the assignment.
3698
  - `rhs.valid() == false`.
3699
 
@@ -3701,16 +4897,16 @@ shared_future& operator=(shared_future&& rhs) noexcept;
3701
  shared_future& operator=(const shared_future& rhs) noexcept;
3702
  ```
3703
 
3704
  *Effects:*
3705
 
3706
- - Releases any shared state ([[futures.state]]);
3707
  - assigns the contents of `rhs` to `*this`. \[*Note 4*: As a result,
3708
  `*this` refers to the same shared state as `rhs` (if
3709
  any). — *end note*]
3710
 
3711
- *Postconditions:* `valid() == rhs.valid()`.
3712
 
3713
  ``` cpp
3714
  const R& shared_future::get() const;
3715
  R& shared_future<R&>::get() const;
3716
  void shared_future<void>::get() const;
@@ -3720,12 +4916,11 @@ void shared_future<void>::get() const;
3720
  specializations differ only in the return type and return value of the
3721
  member function `get`. — *end note*]
3722
 
3723
  [*Note 2*: Access to a value object stored in the shared state is
3724
  unsynchronized, so programmers should apply only those operations on `R`
3725
- that do not introduce a data
3726
- race ([[intro.multithread]]). — *end note*]
3727
 
3728
  *Effects:* `wait()`s until the shared state is ready, then retrieves the
3729
  value stored in the shared state.
3730
 
3731
  *Returns:*
@@ -3738,11 +4933,11 @@ value stored in the shared state.
3738
  returned the reference. — *end note*]
3739
  - `shared_future<R&>::get()` returns the reference stored as value in
3740
  the object’s shared state.
3741
  - `shared_future<void>::get()` returns nothing.
3742
 
3743
- *Throws:* the stored exception, if an exception was stored in the shared
3744
  state.
3745
 
3746
  ``` cpp
3747
  bool valid() const noexcept;
3748
  ```
@@ -3759,144 +4954,145 @@ void wait() const;
3759
  template<class Rep, class Period>
3760
  future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
3761
  ```
3762
 
3763
  *Effects:* None if the shared state contains a deferred
3764
- function ([[futures.async]]), otherwise blocks until the shared state
3765
- is ready or until the relative timeout ([[thread.req.timing]])
3766
- specified by `rel_time` has expired.
3767
 
3768
  *Returns:*
3769
 
3770
  - `future_status::deferred` if the shared state contains a deferred
3771
  function.
3772
  - `future_status::ready` if the shared state is ready.
3773
  - `future_status::timeout` if the function is returning because the
3774
- relative timeout ([[thread.req.timing]]) specified by `rel_time` has
3775
  expired.
3776
 
3777
- *Throws:* timeout-related exceptions ([[thread.req.timing]]).
3778
 
3779
  ``` cpp
3780
  template<class Clock, class Duration>
3781
  future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
3782
  ```
3783
 
3784
  *Effects:* None if the shared state contains a deferred
3785
- function ([[futures.async]]), otherwise blocks until the shared state
3786
- is ready or until the absolute timeout ([[thread.req.timing]])
3787
- specified by `abs_time` has expired.
3788
 
3789
  *Returns:*
3790
 
3791
  - `future_status::deferred` if the shared state contains a deferred
3792
  function.
3793
  - `future_status::ready` if the shared state is ready.
3794
  - `future_status::timeout` if the function is returning because the
3795
- absolute timeout ([[thread.req.timing]]) specified by `abs_time` has
3796
  expired.
3797
 
3798
- *Throws:* timeout-related exceptions ([[thread.req.timing]]).
3799
 
3800
  ### Function template `async` <a id="futures.async">[[futures.async]]</a>
3801
 
3802
  The function template `async` provides a mechanism to launch a function
3803
  potentially in a new thread and provides the result of the function in a
3804
  `future` object with which it shares a shared state.
3805
 
3806
  ``` cpp
3807
  template<class F, class... Args>
3808
- future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
3809
  async(F&& f, Args&&... args);
3810
  template<class F, class... Args>
3811
- future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
3812
  async(launch policy, F&& f, Args&&... args);
3813
  ```
3814
 
3815
- *Requires:* `F` and each `Ti` in `Args` shall satisfy the
3816
- `MoveConstructible` requirements, and
3817
 
3818
- ``` cpp
3819
- INVOKE(DECAY_COPY(std::forward<F>(f)),
3820
- DECAY_COPY(std::forward<Args>(args))...) // see [func.require] [thread.thread.constr]
3821
- ```
 
3822
 
3823
- shall be a valid expression.
 
3824
 
3825
  *Effects:* The first function behaves the same as a call to the second
3826
  function with a `policy` argument of `launch::async | launch::deferred`
3827
  and the same arguments for `F` and `Args`. The second function creates a
3828
  shared state that is associated with the returned `future` object. The
3829
  further behavior of the second function depends on the `policy` argument
3830
  as follows (if more than one of these conditions applies, the
3831
  implementation may choose any of the corresponding policies):
3832
 
3833
  - If `launch::async` is set in `policy`, calls
3834
- *INVOKE*(*DECAY_COPY*(std::forward\<F\>(f)),
3835
- *DECAY_COPY*(std::forward\<Args\>(args))...) ([[func.require]],
3836
  [[thread.thread.constr]]) as if in a new thread of execution
3837
- represented by a `thread` object with the calls to *DECAY_COPY*()
3838
  being evaluated in the thread that called `async`. Any return value is
3839
  stored as the result in the shared state. Any exception propagated
3840
- from the execution of *INVOKE*(*DECAY_COPY*(std::forward\<F\>(f)),
3841
- *DECAY_COPY*(std::forward\<Args\>(args))...) is stored as the
3842
- exceptional result in the shared state. The `thread` object is stored
3843
- in the shared state and affects the behavior of any asynchronous
3844
- return objects that reference that state.
3845
  - If `launch::deferred` is set in `policy`, stores
3846
- *DECAY_COPY*(std::forward\<F\>(f)) and
3847
- *DECAY_COPY*(std::forward\<Args\>(args))... in the shared state. These
3848
  copies of `f` and `args` constitute a *deferred function*. Invocation
3849
- of the deferred function evaluates *INVOKE*(std::move(g),
3850
- std::move(xyz)) where `g` is the stored value of
3851
- *DECAY_COPY*(std::forward\<F\>(f)) and `xyz` is the stored copy of
3852
- *DECAY_COPY*(std::forward\<Args\>(args)).... Any return value is
3853
  stored as the result in the shared state. Any exception propagated
3854
  from the execution of the deferred function is stored as the
3855
  exceptional result in the shared state. The shared state is not made
3856
  ready until the function has completed. The first call to a non-timed
3857
- waiting function ([[futures.state]]) on an asynchronous return object
3858
- referring to this shared state shall invoke the deferred function in
3859
- the thread that called the waiting function. Once evaluation of
3860
- *INVOKE*(std::move(g), std::move(xyz)) begins, the function is no
3861
  longer considered deferred. \[*Note 1*: If this policy is specified
3862
  together with other policies, such as when using a `policy` value of
3863
  `launch::async | launch::deferred`, implementations should defer
3864
  invocation or the selection of the policy when no more concurrency can
3865
  be effectively exploited. — *end note*]
3866
  - If no value is set in the launch policy, or a value is set that is
3867
- neither specified in this International Standard nor by the
3868
- implementation, the behavior is undefined.
3869
 
3870
  *Returns:* An object of type
3871
  `future<invoke_result_t<decay_t<F>, decay_t<Args>...>``>` that refers to
3872
  the shared state created by this call to `async`.
3873
 
3874
  [*Note 1*: If a future obtained from `async` is moved outside the local
3875
- scope, other code that uses the future must be aware that the future’s
3876
- destructor may block for the shared state to become
3877
  ready. — *end note*]
3878
 
3879
  *Synchronization:* Regardless of the provided `policy` argument,
3880
 
3881
- - the invocation of `async` synchronizes with ([[intro.multithread]])
3882
- the invocation of `f`. \[*Note 2*: This statement applies even when
3883
- the corresponding `future` object is moved to another
3884
  thread. — *end note*] ; and
3885
  - the completion of the function `f` is sequenced
3886
- before ([[intro.multithread]]) the shared state is made ready.
3887
  \[*Note 3*: `f` might not be called at all, so its completion might
3888
  never happen. — *end note*]
3889
 
3890
  If the implementation chooses the `launch::async` policy,
3891
 
3892
  - a call to a waiting function on an asynchronous return object that
3893
  shares the shared state created by this `async` call shall block until
3894
  the associated thread has completed, as if joined, or else time
3895
- out ([[thread.thread.member]]);
3896
  - the associated thread completion synchronizes
3897
- with ([[intro.multithread]]) the return from the first function that
3898
  successfully detects the ready status of the shared state or with the
3899
  return from the last function that releases the shared state,
3900
  whichever happens first.
3901
 
3902
  *Throws:* `system_error` if `policy == launch::async` and the
@@ -3956,86 +5152,79 @@ namespace std {
3956
  void operator()(ArgTypes... );
3957
  void make_ready_at_thread_exit(ArgTypes...);
3958
 
3959
  void reset();
3960
  };
 
3961
  template<class R, class... ArgTypes>
3962
  void swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y) noexcept;
3963
- template <class R, class Alloc>
3964
- struct uses_allocator<packaged_task<R>, Alloc>;
3965
  }
3966
  ```
3967
 
3968
- #### `packaged_task` member functions <a id="futures.task.members">[[futures.task.members]]</a>
3969
 
3970
  ``` cpp
3971
  packaged_task() noexcept;
3972
  ```
3973
 
3974
- *Effects:* Constructs a `packaged_task` object with no shared state and
3975
- no stored task.
3976
 
3977
  ``` cpp
3978
  template<class F>
3979
  packaged_task(F&& f);
3980
  ```
3981
 
3982
- *Requires:* *INVOKE*\<R\>(f, t1, t2, ..., tN), where `t1, t2, ..., tN`
3983
- are values of the corresponding types in `ArgTypes...`, shall be a valid
3984
- expression. Invoking a copy of `f` shall behave the same as invoking
 
 
 
3985
  `f`.
3986
 
3987
- *Remarks:* This constructor shall not participate in overload resolution
3988
- if `decay_t<F>` is the same type as `packaged_task<R(ArgTypes...)>`.
3989
-
3990
  *Effects:* Constructs a new `packaged_task` object with a shared state
3991
  and initializes the object’s stored task with `std::forward<F>(f)`.
3992
 
3993
- *Throws:*
3994
-
3995
- - Any exceptions thrown by the copy or move constructor of `f`.
3996
- - For the first version, `bad_alloc` if memory for the internal data
3997
- structures could not be allocated.
3998
- - For the second version, any exceptions thrown by
3999
- `allocator_traits<Allocator>::template`
4000
- `rebind_traits<`*`unspecified`*`>::allocate`.
4001
 
4002
  ``` cpp
4003
  packaged_task(packaged_task&& rhs) noexcept;
4004
  ```
4005
 
4006
- *Effects:* Constructs a new `packaged_task` object and transfers
4007
- ownership of `rhs`’s shared state to `*this`, leaving `rhs` with no
4008
- shared state. Moves the stored task from `rhs` to `*this`.
4009
 
4010
- *Postconditions:* `rhs` has no shared state.
4011
 
4012
  ``` cpp
4013
  packaged_task& operator=(packaged_task&& rhs) noexcept;
4014
  ```
4015
 
4016
  *Effects:*
4017
 
4018
- - Releases any shared state ([[futures.state]]);
4019
  - calls `packaged_task(std::move(rhs)).swap(*this)`.
4020
 
4021
  ``` cpp
4022
  ~packaged_task();
4023
  ```
4024
 
4025
- *Effects:* Abandons any shared state ([[futures.state]]).
4026
 
4027
  ``` cpp
4028
  void swap(packaged_task& other) noexcept;
4029
  ```
4030
 
4031
  *Effects:* Exchanges the shared states and stored tasks of `*this` and
4032
  `other`.
4033
 
4034
- *Postconditions:* `*this` has the same shared state and stored task (if
4035
- any) as `other` prior to the call to `swap`. `other` has the same shared
4036
- state and stored task (if any) as `*this` prior to the call to `swap`.
4037
 
4038
  ``` cpp
4039
  bool valid() const noexcept;
4040
  ```
4041
 
@@ -4046,11 +5235,18 @@ future<R> get_future();
4046
  ```
4047
 
4048
  *Returns:* A `future` object that shares the same shared state as
4049
  `*this`.
4050
 
4051
- *Throws:* a `future_error` object if an error occurs.
 
 
 
 
 
 
 
4052
 
4053
  *Error conditions:*
4054
 
4055
  - `future_already_retrieved` if `get_future` has already been called on
4056
  a `packaged_task` object with the same shared state as `*this`.
@@ -4058,19 +5254,19 @@ future<R> get_future();
4058
 
4059
  ``` cpp
4060
  void operator()(ArgTypes... args);
4061
  ```
4062
 
4063
- *Effects:* As if by *INVOKE*\<R\>(f, t1, t2, ..., tN), where `f` is the
4064
- stored task of `*this` and `t1, t2, ..., tN` are the values in
4065
- `args...`. If the task returns normally, the return value is stored as
4066
- the asynchronous result in the shared state of `*this`, otherwise the
4067
- exception thrown by the task is stored. The shared state of `*this` is
4068
- made ready, and any threads blocked in a function waiting for the shared
4069
- state of `*this` to become ready are unblocked.
4070
 
4071
- *Throws:* a `future_error` exception object if there is no shared state
4072
  or the stored task has already been invoked.
4073
 
4074
  *Error conditions:*
4075
 
4076
  - `promise_already_satisfied` if the stored task has already been
@@ -4079,19 +5275,19 @@ or the stored task has already been invoked.
4079
 
4080
  ``` cpp
4081
  void make_ready_at_thread_exit(ArgTypes... args);
4082
  ```
4083
 
4084
- *Effects:* As if by *INVOKE*\<R\>(f, t1, t2, ..., tN), where `f` is the
4085
- stored task and `t1, t2, ..., tN` are the values in `args...`. If the
4086
- task returns normally, the return value is stored as the asynchronous
4087
- result in the shared state of `*this`, otherwise the exception thrown by
4088
- the task is stored. In either case, this shall be done without making
4089
- that state ready ([[futures.state]]) immediately. Schedules the shared
4090
- state to be made ready when the current thread exits, after all objects
4091
- of thread storage duration associated with the current thread have been
4092
- destroyed.
4093
 
4094
  *Throws:* `future_error` if an error condition occurs.
4095
 
4096
  *Error conditions:*
4097
 
@@ -4104,77 +5300,99 @@ void reset();
4104
  ```
4105
 
4106
  *Effects:* As if `*this = packaged_task(std::move(f))`, where `f` is the
4107
  task stored in `*this`.
4108
 
4109
- [*Note 1*: This constructs a new shared state for `*this`. The old
4110
- state is abandoned ([[futures.state]]). — *end note*]
4111
 
4112
  *Throws:*
4113
 
4114
  - `bad_alloc` if memory for the new shared state could not be allocated.
4115
  - any exception thrown by the move constructor of the task stored in the
4116
  shared state.
4117
  - `future_error` with an error condition of `no_state` if `*this` has no
4118
  shared state.
4119
 
4120
- #### `packaged_task` globals <a id="futures.task.nonmembers">[[futures.task.nonmembers]]</a>
4121
 
4122
  ``` cpp
4123
  template<class R, class... ArgTypes>
4124
  void swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y) noexcept;
4125
  ```
4126
 
4127
  *Effects:* As if by `x.swap(y)`.
4128
 
4129
- ``` cpp
4130
- template <class R, class Alloc>
4131
- struct uses_allocator<packaged_task<R>, Alloc>
4132
- : true_type { };
4133
- ```
4134
-
4135
- *Requires:* `Alloc` shall be an Allocator ([[allocator.requirements]]).
4136
-
4137
  <!-- Link reference definitions -->
4138
  [alg.sorting]: algorithms.md#alg.sorting
4139
- [allocator.requirements]: library.md#allocator.requirements
4140
  [atomics]: atomics.md#atomics
 
4141
  [basic.life]: basic.md#basic.life
4142
  [basic.stc.thread]: basic.md#basic.stc.thread
4143
  [bitmask.types]: library.md#bitmask.types
4144
- [class]: class.md#class
4145
- [condition_variable.syn]: #condition_variable.syn
 
 
 
 
 
 
4146
  [except.terminate]: except.md#except.terminate
4147
  [func.require]: utilities.md#func.require
4148
  [future.syn]: #future.syn
4149
  [futures]: #futures
4150
  [futures.async]: #futures.async
4151
  [futures.errors]: #futures.errors
4152
- [futures.future_error]: #futures.future_error
4153
  [futures.overview]: #futures.overview
4154
  [futures.promise]: #futures.promise
4155
- [futures.shared_future]: #futures.shared_future
4156
  [futures.state]: #futures.state
4157
  [futures.task]: #futures.task
4158
  [futures.task.members]: #futures.task.members
4159
  [futures.task.nonmembers]: #futures.task.nonmembers
4160
- [futures.unique_future]: #futures.unique_future
4161
- [intro.multithread]: intro.md#intro.multithread
 
 
4162
  [mutex.syn]: #mutex.syn
4163
  [res.on.data.races]: library.md#res.on.data.races
4164
  [res.on.exception.handling]: library.md#res.on.exception.handling
4165
- [shared_mutex.syn]: #shared_mutex.syn
 
 
 
 
 
 
 
 
 
 
 
4166
  [syserr]: diagnostics.md#syserr
4167
  [syserr.syserr]: diagnostics.md#syserr.syserr
4168
- [tab:thread.lib.summary]: #tab:thread.lib.summary
4169
  [thread]: #thread
 
 
4170
  [thread.condition]: #thread.condition
4171
  [thread.condition.condvar]: #thread.condition.condvar
4172
  [thread.condition.condvarany]: #thread.condition.condvarany
4173
  [thread.condition.nonmember]: #thread.condition.nonmember
4174
- [thread.decaycopy]: #thread.decaycopy
 
 
4175
  [thread.general]: #thread.general
 
 
 
 
 
 
 
 
4176
  [thread.lock]: #thread.lock
4177
  [thread.lock.algorithm]: #thread.lock.algorithm
4178
  [thread.lock.guard]: #thread.lock.guard
4179
  [thread.lock.scoped]: #thread.lock.scoped
4180
  [thread.lock.shared]: #thread.lock.shared
@@ -4204,14 +5422,20 @@ template <class R, class Alloc>
4204
  [thread.req.lockable.req]: #thread.req.lockable.req
4205
  [thread.req.lockable.timed]: #thread.req.lockable.timed
4206
  [thread.req.native]: #thread.req.native
4207
  [thread.req.paramname]: #thread.req.paramname
4208
  [thread.req.timing]: #thread.req.timing
 
 
4209
  [thread.sharedmutex.class]: #thread.sharedmutex.class
4210
  [thread.sharedmutex.requirements]: #thread.sharedmutex.requirements
4211
  [thread.sharedtimedmutex.class]: #thread.sharedtimedmutex.class
4212
  [thread.sharedtimedmutex.requirements]: #thread.sharedtimedmutex.requirements
 
 
 
 
4213
  [thread.syn]: #thread.syn
4214
  [thread.thread.algorithm]: #thread.thread.algorithm
4215
  [thread.thread.assign]: #thread.thread.assign
4216
  [thread.thread.class]: #thread.thread.class
4217
  [thread.thread.constr]: #thread.thread.constr
@@ -4222,15 +5446,15 @@ template <class R, class Alloc>
4222
  [thread.thread.this]: #thread.thread.this
4223
  [thread.threads]: #thread.threads
4224
  [thread.timedmutex.class]: #thread.timedmutex.class
4225
  [thread.timedmutex.recursive]: #thread.timedmutex.recursive
4226
  [thread.timedmutex.requirements]: #thread.timedmutex.requirements
4227
- [time]: utilities.md#time
4228
- [time.clock]: utilities.md#time.clock
4229
- [time.clock.req]: utilities.md#time.clock.req
4230
- [time.duration]: utilities.md#time.duration
4231
- [time.point]: utilities.md#time.point
4232
  [unord.hash]: utilities.md#unord.hash
4233
 
4234
  [^1]: All implementations for which standard time units are meaningful
4235
  must necessarily have a steady clock within their hardware
4236
  implementation.
 
1
  # Thread support library <a id="thread">[[thread]]</a>
2
 
3
  ## General <a id="thread.general">[[thread.general]]</a>
4
 
5
  The following subclauses describe components to create and manage
6
+ threads [[intro.multithread]], perform mutual exclusion, and communicate
7
+ conditions and values between threads, as summarized in
8
+ [[thread.summary]].
9
 
10
+ **Table: Thread support library summary** <a id="thread.summary">[thread.summary]</a>
11
 
12
  | Subclause | | Header |
13
+ | -------------------- | ------------------- | --------------------------- |
14
  | [[thread.req]] | Requirements | |
15
+ | [[thread.stoptoken]] | Stop tokens | `<stop_token>` |
16
  | [[thread.threads]] | Threads | `<thread>` |
17
+ | [[thread.mutex]] | Mutual exclusion | `<mutex>`, `<shared_mutex>` |
 
18
  | [[thread.condition]] | Condition variables | `<condition_variable>` |
19
+ | [[thread.sema]] | Semaphores | `<semaphore>` |
20
+ | [[thread.coord]] | Coordination types | `<latch>` `<barrier>` |
21
  | [[futures]] | Futures | `<future>` |
22
 
23
 
24
  ## Requirements <a id="thread.req">[[thread.req]]</a>
25
 
26
  ### Template parameter names <a id="thread.req.paramname">[[thread.req.paramname]]</a>
27
 
28
  Throughout this Clause, the names of template parameters are used to
29
  express type requirements. If a template parameter is named `Predicate`,
30
  `operator()` applied to the template argument shall return a value that
31
+ is convertible to `bool`. If a template parameter is named `Clock`, the
32
+ corresponding template argument shall be a type `C` for which
33
+ `is_clock_v<C>` is `true`; otherwise the program is ill-formed.
34
 
35
  ### Exceptions <a id="thread.req.exception">[[thread.req.exception]]</a>
36
 
37
  Some functions described in this Clause are specified to throw
38
+ exceptions of type `system_error` [[syserr.syserr]]. Such exceptions are
39
+ thrown if any of the function’s error conditions is detected or a call
40
+ to an operating system or other underlying API results in an error that
41
+ prevents the library function from meeting its specifications. Failure
42
+ to allocate storage is reported as described in 
43
+ [[res.on.exception.handling]].
44
 
45
  [*Example 1*: Consider a function in this clause that is specified to
46
  throw exceptions of type `system_error` and specifies error conditions
47
  that include `operation_not_permitted` for a thread that does not have
48
  the privilege to perform the operation. Assume that, during the
49
  execution of this function, an `errno` of `EPERM` is reported by a POSIX
50
  API call used by the implementation. Since POSIX specifies an `errno` of
51
  `EPERM` when “the caller does not have the privilege to perform the
52
  operation”, the implementation maps `EPERM` to an `error_condition` of
53
+ `operation_not_permitted` [[syserr]] and an exception of type
54
  `system_error` is thrown. — *end example*]
55
 
56
  The `error_code` reported by such an exception’s `code()` member
57
+ function compares equal to one of the conditions specified in the
58
  function’s error condition element.
59
 
60
  ### Native handles <a id="thread.req.native">[[thread.req.native]]</a>
61
 
62
  Several classes described in this Clause have members
 
80
  Ideally, this delay would be zero. Further, any contention for processor
81
  and memory resources induces a “quality of management” delay, expressed
82
  as duration Dₘ. The delay durations may vary from timeout to timeout,
83
  but in all cases shorter is better.
84
 
85
+ The functions whose names end in `_for` take an argument that specifies
86
+ a duration. These functions produce relative timeouts. Implementations
87
+ should use a steady clock to measure time for these functions.[^1] Given
88
+ a duration argument Dₜ, the real-time duration of the timeout is
89
+ Dₜ + Dᵢ + Dₘ.
90
 
91
+ The functions whose names end in `_until` take an argument that
92
  specifies a time point. These functions produce absolute timeouts.
93
  Implementations should use the clock specified in the time point to
94
  measure time for these functions. Given a clock time point argument Cₜ,
95
  the clock time point of the return from timeout should be Cₜ + Dᵢ + Dₘ
96
  when the clock is not adjusted during the timeout. If the clock is
97
  adjusted to the time Cₐ during the timeout, the behavior should be as
98
  follows:
99
 
100
+ - if Cₐ > Cₜ, the waiting function should wake as soon as possible,
101
+ i.e., Cₐ + Dᵢ + Dₘ, since the timeout is already satisfied. This
102
  specification may result in the total duration of the wait decreasing
103
+ when measured against a steady clock.
104
+ - if Cₐ Cₜ, the waiting function should not time out until
105
+ `Clock::now()` returns a time Cₙ Cₜ, i.e., waking at Cₜ + Dᵢ + Dₘ.
106
+ \[*Note 1*: When the clock is adjusted backwards, this specification
107
+ can result in the total duration of the wait increasing when measured
108
  against a steady clock. When the clock is adjusted forwards, this
109
+ specification can result in the total duration of the wait decreasing
110
  when measured against a steady clock. — *end note*]
111
 
112
+ An implementation returns from such a timeout at any point from the time
113
+ specified above to the time it would return from a steady-clock relative
114
+ timeout on the difference between Cₜ and the time point of the call to
115
+ the `_until` function.
116
 
117
+ [*Note 2*: Implementations should decrease the duration of the wait
118
  when the clock is adjusted forwards. — *end note*]
119
 
120
+ [*Note 3*: If the clock is not synchronized with a steady clock, e.g.,
121
  a CPU time clock, these timeouts might not provide useful
122
  functionality. — *end note*]
123
 
124
  The resolution of timing provided by an implementation depends on both
125
  operating system and hardware. The finest resolution provided by an
126
  implementation is called the *native resolution*.
127
 
128
+ Implementation-provided clocks that are used for these functions meet
129
+ the *Cpp17TrivialClock* requirements [[time.clock.req]].
130
 
131
  A function that takes an argument which specifies a timeout will throw
132
  if, during its execution, a clock, time point, or time duration throws
133
  an exception. Such exceptions are referred to as *timeout-related
134
  exceptions*.
135
 
136
+ [*Note 4*: Instantiations of clock, time point and duration types
137
  supplied by the implementation as specified in  [[time.clock]] do not
138
  throw exceptions. — *end note*]
139
 
140
+ ### Requirements for *Cpp17Lockable* types <a id="thread.req.lockable">[[thread.req.lockable]]</a>
141
 
142
  #### In general <a id="thread.req.lockable.general">[[thread.req.lockable.general]]</a>
143
 
144
  An *execution agent* is an entity such as a thread that may perform work
145
  in parallel with other execution agents.
146
 
147
+ [*Note 1*: Implementations or users can introduce other kinds of agents
148
  such as processes or thread-pool tasks. — *end note*]
149
 
150
+ The calling agent is determined by context, e.g., the calling thread
151
+ that contains the call, and so on.
152
 
153
  [*Note 2*: Some lockable objects are “agent oblivious” in that they
154
  work for any execution agent model because they do not determine or
155
  store the agent’s ID (e.g., an ordinary spin lock). — *end note*]
156
 
157
+ The standard library templates `unique_lock` [[thread.lock.unique]],
158
+ `shared_lock` [[thread.lock.shared]], `scoped_lock`
159
+ [[thread.lock.scoped]], `lock_guard` [[thread.lock.guard]], `lock`,
160
+ `try_lock` [[thread.lock.algorithm]], and `condition_variable_any`
161
+ [[thread.condition.condvarany]] all operate on user-supplied lockable
162
+ objects. The *Cpp17BasicLockable* requirements, the *Cpp17Lockable*
163
+ requirements, and the *Cpp17TimedLockable* requirements list the
164
+ requirements imposed by these library types in order to acquire or
165
+ release ownership of a `lock` by a given execution agent.
166
 
167
  [*Note 3*: The nature of any lock ownership and any synchronization it
168
+ entails are not part of these requirements. — *end note*]
169
 
170
+ #### *Cpp17BasicLockable* requirements <a id="thread.req.lockable.basic">[[thread.req.lockable.basic]]</a>
171
 
172
+ A type `L` meets the *Cpp17BasicLockable* requirements if the following
173
  expressions are well-formed and have the specified semantics (`m`
174
  denotes a value of type `L`).
175
 
176
  ``` cpp
177
  m.lock()
 
183
 
184
  ``` cpp
185
  m.unlock()
186
  ```
187
 
188
+ *Preconditions:* The current execution agent holds a lock on `m`.
189
 
190
  *Effects:* Releases a lock on `m` held by the current execution agent.
191
 
192
  *Throws:* Nothing.
193
 
194
+ #### *Cpp17Lockable* requirements <a id="thread.req.lockable.req">[[thread.req.lockable.req]]</a>
195
 
196
+ A type `L` meets the *Cpp17Lockable* requirements if it meets the
197
+ *Cpp17BasicLockable* requirements and the following expressions are
198
  well-formed and have the specified semantics (`m` denotes a value of
199
  type `L`).
200
 
201
  ``` cpp
202
  m.try_lock()
 
208
 
209
  *Return type:* `bool`.
210
 
211
  *Returns:* `true` if the lock was acquired, `false` otherwise.
212
 
213
+ #### *Cpp17TimedLockable* requirements <a id="thread.req.lockable.timed">[[thread.req.lockable.timed]]</a>
214
 
215
+ A type `L` meets the *Cpp17TimedLockable* requirements if it meets the
216
+ *Cpp17Lockable* requirements and the following expressions are
217
+ well-formed and have the specified semantics (`m` denotes a value of
218
+ type `L`, `rel_time` denotes a value of an instantiation of `duration`
219
+ [[time.duration]], and `abs_time` denotes a value of an instantiation of
220
+ `time_point` [[time.point]]).
221
 
222
  ``` cpp
223
  m.try_lock_for(rel_time)
224
  ```
225
 
226
  *Effects:* Attempts to acquire a lock for the current execution agent
227
+ within the relative timeout [[thread.req.timing]] specified by
228
+ `rel_time`. The function will not return within the timeout specified by
229
+ `rel_time` unless it has obtained a lock on `m` for the current
230
+ execution agent. If an exception is thrown then a lock has not been
231
+ acquired for the current execution agent.
232
 
233
  *Return type:* `bool`.
234
 
235
  *Returns:* `true` if the lock was acquired, `false` otherwise.
236
 
237
  ``` cpp
238
  m.try_lock_until(abs_time)
239
  ```
240
 
241
  *Effects:* Attempts to acquire a lock for the current execution agent
242
+ before the absolute timeout [[thread.req.timing]] specified by
243
+ `abs_time`. The function will not return before the timeout specified by
244
+ `abs_time` unless it has obtained a lock on `m` for the current
245
+ execution agent. If an exception is thrown then a lock has not been
246
+ acquired for the current execution agent.
247
 
248
  *Return type:* `bool`.
249
 
250
  *Returns:* `true` if the lock was acquired, `false` otherwise.
251
 
252
+ ## Stop tokens <a id="thread.stoptoken">[[thread.stoptoken]]</a>
253
 
254
+ ### Introduction <a id="thread.stoptoken.intro">[[thread.stoptoken.intro]]</a>
255
+
256
+ This clause describes components that can be used to asynchonously
257
+ request that an operation stops execution in a timely manner, typically
258
+ because the result is no longer required. Such a request is called a
259
+ *stop request*.
260
+
261
+ `stop_source`, `stop_token`, and `stop_callback` implement semantics of
262
+ shared ownership of a *stop state*. Any `stop_source`, `stop_token`, or
263
+ `stop_callback` that shares ownership of the same stop state is an
264
+ *associated* `stop_source`, `stop_token`, or `stop_callback`,
265
+ respectively. The last remaining owner of the stop state automatically
266
+ releases the resources associated with the stop state.
267
+
268
+ A `stop_token` can be passed to an operation which can either
269
+
270
+ - actively poll the token to check if there has been a stop request, or
271
+ - register a callback using the `stop_callback` class template which
272
+ will be called in the event that a stop request is made.
273
+
274
+ A stop request made via a `stop_source` will be visible to all
275
+ associated `stop_token` and `stop_source` objects. Once a stop request
276
+ has been made it cannot be withdrawn (a subsequent stop request has no
277
+ effect).
278
+
279
+ Callbacks registered via a `stop_callback` object are called when a stop
280
+ request is first made by any associated `stop_source` object.
281
+
282
+ Calls to the functions `request_stop`, `stop_requested`, and
283
+ `stop_possible` do not introduce data races. A call to `request_stop`
284
+ that returns `true` synchronizes with a call to `stop_requested` on an
285
+ associated `stop_token` or `stop_source` object that returns `true`.
286
+ Registration of a callback synchronizes with the invocation of that
287
+ callback.
288
+
289
+ ### Header `<stop_token>` synopsis <a id="thread.stoptoken.syn">[[thread.stoptoken.syn]]</a>
290
+
291
+ ``` cpp
292
+ namespace std {
293
+ // [stoptoken], class stop_token
294
+ class stop_token;
295
+
296
+ // [stopsource], class stop_source
297
+ class stop_source;
298
+
299
+ // no-shared-stop-state indicator
300
+ struct nostopstate_t {
301
+ explicit nostopstate_t() = default;
302
+ };
303
+ inline constexpr nostopstate_t nostopstate{};
304
+
305
+ // [stopcallback], class stop_callback
306
+ template<class Callback>
307
+ class stop_callback;
308
+ }
309
+ ```
310
+
311
+ ### Class `stop_token` <a id="stoptoken">[[stoptoken]]</a>
312
+
313
+ The class `stop_token` provides an interface for querying whether a stop
314
+ request has been made (`stop_requested`) or can ever be made
315
+ (`stop_possible`) using an associated `stop_source` object (
316
+ [[stopsource]]). A `stop_token` can also be passed to a `stop_callback`
317
+ [[stopcallback]] constructor to register a callback to be called when a
318
+ stop request has been made from an associated `stop_source`.
319
+
320
+ ``` cpp
321
+ namespace std {
322
+ class stop_token {
323
+ public:
324
+ // [stoptoken.cons], constructors, copy, and assignment
325
+ stop_token() noexcept;
326
+
327
+ stop_token(const stop_token&) noexcept;
328
+ stop_token(stop_token&&) noexcept;
329
+ stop_token& operator=(const stop_token&) noexcept;
330
+ stop_token& operator=(stop_token&&) noexcept;
331
+ ~stop_token();
332
+ void swap(stop_token&) noexcept;
333
+
334
+ // [stoptoken.mem], stop handling
335
+ [[nodiscard]] bool stop_requested() const noexcept;
336
+ [[nodiscard]] bool stop_possible() const noexcept;
337
+
338
+ [[nodiscard]] friend bool operator==(const stop_token& lhs, const stop_token& rhs) noexcept;
339
+ friend void swap(stop_token& lhs, stop_token& rhs) noexcept;
340
+ };
341
+ }
342
+ ```
343
+
344
+ #### Constructors, copy, and assignment <a id="stoptoken.cons">[[stoptoken.cons]]</a>
345
+
346
+ ``` cpp
347
+ stop_token() noexcept;
348
+ ```
349
+
350
+ *Ensures:* `stop_possible()` is `false` and `stop_requested()` is
351
+ `false`.
352
+
353
+ [*Note 1*: Because the created `stop_token` object can never receive a
354
+ stop request, no resources are allocated for a stop
355
+ state. — *end note*]
356
+
357
+ ``` cpp
358
+ stop_token(const stop_token& rhs) noexcept;
359
+ ```
360
+
361
+ *Ensures:* `*this == rhs` is `true`.
362
+
363
+ [*Note 2*: `*this` and `rhs` share the ownership of the same stop
364
+ state, if any. — *end note*]
365
+
366
+ ``` cpp
367
+ stop_token(stop_token&& rhs) noexcept;
368
+ ```
369
+
370
+ *Ensures:* `*this` contains the value of `rhs` prior to the start of
371
+ construction and `rhs.stop_possible()` is `false`.
372
+
373
+ ``` cpp
374
+ ~stop_token();
375
+ ```
376
+
377
+ *Effects:* Releases ownership of the stop state, if any.
378
+
379
+ ``` cpp
380
+ stop_token& operator=(const stop_token& rhs) noexcept;
381
+ ```
382
+
383
+ *Effects:* Equivalent to: `stop_token(rhs).swap(*this)`.
384
+
385
+ *Returns:* `*this`.
386
+
387
+ ``` cpp
388
+ stop_token& operator=(stop_token&& rhs) noexcept;
389
+ ```
390
+
391
+ *Effects:* Equivalent to: `stop_token(std::move(rhs)).swap(*this)`.
392
+
393
+ *Returns:* `*this`.
394
+
395
+ ``` cpp
396
+ void swap(stop_token& rhs) noexcept;
397
+ ```
398
+
399
+ *Effects:* Exchanges the values of `*this` and `rhs`.
400
+
401
+ #### Members <a id="stoptoken.mem">[[stoptoken.mem]]</a>
402
+
403
+ ``` cpp
404
+ [[nodiscard]] bool stop_requested() const noexcept;
405
+ ```
406
+
407
+ *Returns:* `true` if `*this` has ownership of a stop state that has
408
+ received a stop request; otherwise, `false`.
409
+
410
+ ``` cpp
411
+ [[nodiscard]] bool stop_possible() const noexcept;
412
+ ```
413
+
414
+ *Returns:* `false` if:
415
+
416
+ - `*this` does not have ownership of a stop state, or
417
+ - a stop request was not made and there are no associated `stop_source`
418
+ objects;
419
+
420
+ otherwise, `true`.
421
+
422
+ #### Non-member functions <a id="stoptoken.nonmembers">[[stoptoken.nonmembers]]</a>
423
+
424
+ ``` cpp
425
+ [[nodiscard]] bool operator==(const stop_token& lhs, const stop_token& rhs) noexcept;
426
+ ```
427
+
428
+ *Returns:* `true` if `lhs` and `rhs` have ownership of the same stop
429
+ state or if both `lhs` and `rhs` do not have ownership of a stop state;
430
+ otherwise `false`.
431
+
432
+ ``` cpp
433
+ friend void swap(stop_token& x, stop_token& y) noexcept;
434
+ ```
435
+
436
+ *Effects:* Equivalent to: `x.swap(y)`.
437
+
438
+ ### Class `stop_source` <a id="stopsource">[[stopsource]]</a>
439
+
440
+ The class `stop_source` implements the semantics of making a stop
441
+ request. A stop request made on a `stop_source` object is visible to all
442
+ associated `stop_source` and `stop_token` ([[stoptoken]]) objects. Once
443
+ a stop request has been made it cannot be withdrawn (a subsequent stop
444
+ request has no effect).
445
+
446
+ ``` cpp
447
+ namespace std {
448
+ // no-shared-stop-state indicator
449
+ struct nostopstate_t {
450
+ explicit nostopstate_t() = default;
451
+ };
452
+ inline constexpr nostopstate_t nostopstate{};
453
+
454
+ class stop_source {
455
+ public:
456
+ // [stopsource.cons], constructors, copy, and assignment
457
+ stop_source();
458
+ explicit stop_source(nostopstate_t) noexcept;
459
+
460
+ stop_source(const stop_source&) noexcept;
461
+ stop_source(stop_source&&) noexcept;
462
+ stop_source& operator=(const stop_source&) noexcept;
463
+ stop_source& operator=(stop_source&&) noexcept;
464
+ ~stop_source();
465
+ void swap(stop_source&) noexcept;
466
+
467
+ // [stopsource.mem], stop handling
468
+ [[nodiscard]] stop_token get_token() const noexcept;
469
+ [[nodiscard]] bool stop_possible() const noexcept;
470
+ [[nodiscard]] bool stop_requested() const noexcept;
471
+ bool request_stop() noexcept;
472
+
473
+ [[nodiscard]] friend bool
474
+ operator==(const stop_source& lhs, const stop_source& rhs) noexcept;
475
+ friend void swap(stop_source& lhs, stop_source& rhs) noexcept;
476
+ };
477
+ }
478
+ ```
479
+
480
+ #### Constructors, copy, and assignment <a id="stopsource.cons">[[stopsource.cons]]</a>
481
+
482
+ ``` cpp
483
+ stop_source();
484
+ ```
485
+
486
+ *Effects:* Initialises `*this` to have ownership of a new stop state.
487
+
488
+ *Ensures:* `stop_possible()` is `true` and `stop_requested()` is
489
+ `false`.
490
+
491
+ *Throws:* `bad_alloc` if memory could not be allocated for the stop
492
+ state.
493
+
494
+ ``` cpp
495
+ explicit stop_source(nostopstate_t) noexcept;
496
+ ```
497
+
498
+ *Ensures:* `stop_possible()` is `false` and `stop_requested()` is
499
+ `false`.
500
+
501
+ [*Note 1*: No resources are allocated for the state. — *end note*]
502
+
503
+ ``` cpp
504
+ stop_source(const stop_source& rhs) noexcept;
505
+ ```
506
+
507
+ *Ensures:* `*this == rhs` is `true`.
508
+
509
+ [*Note 2*: `*this` and `rhs` share the ownership of the same stop
510
+ state, if any. — *end note*]
511
+
512
+ ``` cpp
513
+ stop_source(stop_source&& rhs) noexcept;
514
+ ```
515
+
516
+ *Ensures:* `*this` contains the value of `rhs` prior to the start of
517
+ construction and `rhs.stop_possible()` is `false`.
518
+
519
+ ``` cpp
520
+ ~stop_source();
521
+ ```
522
+
523
+ *Effects:* Releases ownership of the stop state, if any.
524
+
525
+ ``` cpp
526
+ stop_source& operator=(const stop_source& rhs) noexcept;
527
+ ```
528
+
529
+ *Effects:* Equivalent to: `stop_source(rhs).swap(*this)`.
530
+
531
+ *Returns:* `*this`.
532
+
533
+ ``` cpp
534
+ stop_source& operator=(stop_source&& rhs) noexcept;
535
+ ```
536
+
537
+ *Effects:* Equivalent to: `stop_source(std::move(rhs)).swap(*this)`.
538
+
539
+ *Returns:* `*this`.
540
+
541
+ ``` cpp
542
+ void swap(stop_source& rhs) noexcept;
543
+ ```
544
+
545
+ *Effects:* Exchanges the values of `*this` and `rhs`.
546
+
547
+ #### Members <a id="stopsource.mem">[[stopsource.mem]]</a>
548
+
549
+ ``` cpp
550
+ [[nodiscard]] stop_token get_token() const noexcept;
551
+ ```
552
+
553
+ *Returns:* `stop_token()` if `stop_possible()` is `false`; otherwise a
554
+ new associated `stop_token` object.
555
+
556
+ ``` cpp
557
+ [[nodiscard]] bool stop_possible() const noexcept;
558
+ ```
559
+
560
+ *Returns:* `true` if `*this` has ownership of a stop state; otherwise,
561
+ `false`.
562
+
563
+ ``` cpp
564
+ [[nodiscard]] bool stop_requested() const noexcept;
565
+ ```
566
+
567
+ *Returns:* `true` if `*this` has ownership of a stop state that has
568
+ received a stop request; otherwise, `false`.
569
+
570
+ ``` cpp
571
+ bool request_stop() noexcept;
572
+ ```
573
+
574
+ *Effects:* If `*this` does not have ownership of a stop state, returns
575
+ `false`. Otherwise, atomically determines whether the owned stop state
576
+ has received a stop request, and if not, makes a stop request. The
577
+ determination and making of the stop request are an atomic
578
+ read-modify-write operation [[intro.races]]. If the request was made,
579
+ the callbacks registered by associated `stop_callback` objects are
580
+ synchronously called. If an invocation of a callback exits via an
581
+ exception then `terminate` is called [[except.terminate]].
582
+
583
+ [*Note 1*: A stop request includes notifying all condition variables of
584
+ type `condition_variable_any` temporarily registered during an
585
+ interruptible wait [[thread.condvarany.intwait]]. — *end note*]
586
+
587
+ *Ensures:* `stop_possible()` is `false` or `stop_requested()` is `true`.
588
+
589
+ *Returns:* `true` if this call made a stop request; otherwise `false`.
590
+
591
+ #### Non-member functions <a id="stopsource.nonmembers">[[stopsource.nonmembers]]</a>
592
 
593
  ``` cpp
594
+ [[nodiscard]] friend bool
595
+ operator==(const stop_source& lhs, const stop_source& rhs) noexcept;
596
  ```
597
 
598
+ *Returns:* `true` if `lhs` and `rhs` have ownership of the same stop
599
+ state or if both `lhs` and `rhs` do not have ownership of a stop state;
600
+ otherwise `false`.
601
+
602
+ ``` cpp
603
+ friend void swap(stop_source& x, stop_source& y) noexcept;
604
+ ```
605
+
606
+ *Effects:* Equivalent to: `x.swap(y)`.
607
+
608
+ ### Class template `stop_callback` <a id="stopcallback">[[stopcallback]]</a>
609
+
610
+ ``` cpp
611
+ namespace std {
612
+ template<class Callback>
613
+ class stop_callback {
614
+ public:
615
+ using callback_type = Callback;
616
+
617
+ // [stopcallback.cons], constructors and destructor
618
+ template<class C>
619
+ explicit stop_callback(const stop_token& st, C&& cb)
620
+ noexcept(is_nothrow_constructible_v<Callback, C>);
621
+ template<class C>
622
+ explicit stop_callback(stop_token&& st, C&& cb)
623
+ noexcept(is_nothrow_constructible_v<Callback, C>);
624
+ ~stop_callback();
625
+
626
+ stop_callback(const stop_callback&) = delete;
627
+ stop_callback(stop_callback&&) = delete;
628
+ stop_callback& operator=(const stop_callback&) = delete;
629
+ stop_callback& operator=(stop_callback&&) = delete;
630
+
631
+ private:
632
+ Callback callback; // exposition only
633
+ };
634
+
635
+ template<class Callback>
636
+ stop_callback(stop_token, Callback) -> stop_callback<Callback>;
637
+ }
638
+ ```
639
+
640
+ *Mandates:* `stop_callback` is instantiated with an argument for the
641
+ template parameter `Callback` that satisfies both `invocable` and
642
+ `destructible`.
643
+
644
+ *Preconditions:* `stop_callback` is instantiated with an argument for
645
+ the template parameter `Callback` that models both `invocable` and
646
+ `destructible`.
647
+
648
+ #### Constructors and destructor <a id="stopcallback.cons">[[stopcallback.cons]]</a>
649
+
650
+ ``` cpp
651
+ template<class C>
652
+ explicit stop_callback(const stop_token& st, C&& cb)
653
+ noexcept(is_nothrow_constructible_v<Callback, C>);
654
+ template<class C>
655
+ explicit stop_callback(stop_token&& st, C&& cb)
656
+ noexcept(is_nothrow_constructible_v<Callback, C>);
657
+ ```
658
+
659
+ *Constraints:* `Callback` and `C` satisfy
660
+ `constructible_from<Callback, C>`.
661
+
662
+ *Preconditions:* `Callback` and `C` model
663
+ `constructible_from<Callback, C>`.
664
+
665
+ *Effects:* Initializes `callback` with `std::forward<C>(cb)`. If
666
+ `st.stop_requested()` is `true`, then
667
+ `std::forward<Callback>(callback)()` is evaluated in the current thread
668
+ before the constructor returns. Otherwise, if `st` has ownership of a
669
+ stop state, acquires shared ownership of that stop state and registers
670
+ the callback with that stop state such that
671
+ `std::forward<Callback>(callback)()` is evaluated by the first call to
672
+ `request_stop()` on an associated `stop_source`.
673
+
674
+ *Remarks:* If evaluating `std::forward<Callback>(callback)()` exits via
675
+ an exception, then `terminate` is called [[except.terminate]].
676
+
677
+ *Throws:* Any exception thrown by the initialization of `callback`.
678
+
679
+ ``` cpp
680
+ ~stop_callback();
681
+ ```
682
+
683
+ *Effects:* Unregisters the callback from the owned stop state, if any.
684
+ The destructor does not block waiting for the execution of another
685
+ callback registered by an associated `stop_callback`. If `callback` is
686
+ concurrently executing on another thread, then the return from the
687
+ invocation of `callback` strongly happens before [[intro.races]]
688
+ `callback` is destroyed. If `callback` is executing on the current
689
+ thread, then the destructor does not block [[defns.block]] waiting for
690
+ the return from the invocation of `callback`. Releases ownership of the
691
+ stop state, if any.
692
+
693
  ## Threads <a id="thread.threads">[[thread.threads]]</a>
694
 
695
  [[thread.threads]] describes components that can be used to create and
696
  manage threads.
697
 
 
699
  system threads. — *end note*]
700
 
701
  ### Header `<thread>` synopsis <a id="thread.syn">[[thread.syn]]</a>
702
 
703
  ``` cpp
704
+ #include <compare> // see [compare.syn]
705
+ #include <initializer_list> // see [initializer.list.syn]
706
+
707
  namespace std {
708
  class thread;
709
 
710
  void swap(thread& x, thread& y) noexcept;
711
 
712
+ // [thread.jthread.class] class jthread
713
+ class jthread;
714
+
715
  namespace this_thread {
716
  thread::id get_id() noexcept;
717
 
718
  void yield() noexcept;
719
  template<class Clock, class Duration>
 
743
 
744
  ``` cpp
745
  namespace std {
746
  class thread {
747
  public:
748
+ // types
749
  class id;
750
+ using native_handle_type = implementation-defined; // see~[thread.req.native]
751
 
752
+ // construct/copy/destroy
753
  thread() noexcept;
754
  template<class F, class... Args> explicit thread(F&& f, Args&&... args);
755
  ~thread();
756
  thread(const thread&) = delete;
757
  thread(thread&&) noexcept;
758
  thread& operator=(const thread&) = delete;
759
  thread& operator=(thread&&) noexcept;
760
 
761
+ // members
762
  void swap(thread&) noexcept;
763
  bool joinable() const noexcept;
764
  void join();
765
  void detach();
766
  id get_id() const noexcept;
767
+ native_handle_type native_handle(); // see~[thread.req.native]
768
 
769
+ // static members
770
+ static unsigned int hardware_concurrency() noexcept;
771
  };
772
  }
773
  ```
774
 
775
  #### Class `thread::id` <a id="thread.thread.id">[[thread.thread.id]]</a>
 
780
  public:
781
  id() noexcept;
782
  };
783
 
784
  bool operator==(thread::id x, thread::id y) noexcept;
785
+ strong_ordering operator<=>(thread::id x, thread::id y) noexcept;
 
 
 
 
786
 
787
  template<class charT, class traits>
788
  basic_ostream<charT, traits>&
789
  operator<<(basic_ostream<charT, traits>& out, thread::id id);
790
 
791
+ // hash support
792
  template<class T> struct hash;
793
  template<> struct hash<thread::id>;
794
  }
795
  ```
796
 
797
  An object of type `thread::id` provides a unique identifier for each
798
  thread of execution and a single distinct value for all `thread` objects
799
+ that do not represent a thread of execution [[thread.thread.class]].
800
  Each thread of execution has an associated `thread::id` object that is
801
  not equal to the `thread::id` object of any other thread of execution
802
  and that is not equal to the `thread::id` object of any `thread` object
803
  that does not represent threads of execution.
804
 
805
+ `thread::id` is a trivially copyable class [[class.prop]]. The library
806
+ may reuse the value of a `thread::id` of a terminated thread that can no
807
+ longer be joined.
808
 
809
  [*Note 1*: Relational operators allow `thread::id` objects to be used
810
  as keys in associative containers. — *end note*]
811
 
812
  ``` cpp
813
  id() noexcept;
814
  ```
815
 
816
+ *Ensures:* The constructed object does not represent a thread of
 
 
817
  execution.
818
 
819
  ``` cpp
820
  bool operator==(thread::id x, thread::id y) noexcept;
821
  ```
822
 
823
  *Returns:* `true` only if `x` and `y` represent the same thread of
824
  execution or neither `x` nor `y` represents a thread of execution.
825
 
826
  ``` cpp
827
+ strong_ordering operator<=>(thread::id x, thread::id y) noexcept;
828
  ```
829
 
830
+ Let P(`x`, `y`) be an unspecified total ordering over `thread::id` as
831
+ described in [[alg.sorting]].
832
 
833
+ *Returns:* `strong_ordering::less` if P(`x`, `y`) is `true`. Otherwise,
834
+ `strong_ordering::greater` if P(`y`, `x`) is `true`. Otherwise,
835
+ `strong_ordering::equal`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
836
 
837
  ``` cpp
838
  template<class charT, class traits>
839
  basic_ostream<charT, traits>&
840
  operator<< (basic_ostream<charT, traits>& out, thread::id id);
841
  ```
842
 
843
  *Effects:* Inserts an unspecified text representation of `id` into
844
  `out`. For two objects of type `thread::id` `x` and `y`, if `x == y` the
845
+ `thread::id` objects have the same text representation and if `x != y`
846
+ the `thread::id` objects have distinct text representations.
 
847
 
848
  *Returns:* `out`.
849
 
850
  ``` cpp
851
  template<> struct hash<thread::id>;
852
  ```
853
 
854
+ The specialization is enabled [[unord.hash]].
855
 
856
+ #### Constructors <a id="thread.thread.constr">[[thread.thread.constr]]</a>
857
 
858
  ``` cpp
859
  thread() noexcept;
860
  ```
861
 
862
+ *Effects:* The object does not represent a thread of execution.
 
863
 
864
+ *Ensures:* `get_id() == id()`.
865
 
866
  ``` cpp
867
  template<class F, class... Args> explicit thread(F&& f, Args&&... args);
868
  ```
869
 
870
+ *Constraints:* `remove_cvref_t<F>` is not the same type as `thread`.
871
+
872
+ *Mandates:* The following are all `true`:
873
+
874
+ - `is_constructible_v<decay_t<F>, F>`,
875
+ - `(is_constructible_v<decay_t<Args>, Args> && ...)`,
876
+ - `is_move_constructible_v<decay_t<F>>`,
877
+ - `(is_move_constructible_v<decay_t<Args>> && ...)`, and
878
+ - `is_invocable_v<decay_t<F>, decay_t<Args>...>`.
879
+
880
+ *Preconditions:* `decay_t<F>` and each type in `decay_t<Args>` meet the
881
+ *Cpp17MoveConstructible* requirements.
882
+
883
+ *Effects:* The new thread of execution executes
884
+
885
+ ``` cpp
886
+ invoke(decay-copy(std::forward<F>(f)), decay-copy(std::forward<Args>(args))...)
887
+ ```
888
+
889
+ with the calls to *`decay-copy`* being evaluated in the constructing
890
  thread. Any return value from this invocation is ignored.
891
 
892
  [*Note 1*: This implies that any exceptions not thrown from the
893
  invocation of the copy of `f` will be thrown in the constructing thread,
894
  not the new thread. — *end note*]
895
 
896
+ If the invocation of `invoke` terminates with an uncaught exception,
897
+ `terminate` is called.
 
898
 
899
  *Synchronization:* The completion of the invocation of the constructor
900
  synchronizes with the beginning of the invocation of the copy of `f`.
901
 
902
+ *Ensures:* `get_id() != id()`. `*this` represents the newly started
903
+ thread.
904
 
905
  *Throws:* `system_error` if unable to start the new thread.
906
 
907
  *Error conditions:*
908
 
 
912
 
913
  ``` cpp
914
  thread(thread&& x) noexcept;
915
  ```
916
 
917
+ *Ensures:* `x.get_id() == id()` and `get_id()` returns the value of
918
+ `x.get_id()` prior to the start of construction.
919
 
920
+ #### Destructor <a id="thread.thread.destr">[[thread.thread.destr]]</a>
 
 
 
921
 
922
  ``` cpp
923
  ~thread();
924
  ```
925
 
926
+ *Effects:* If `joinable()`, calls `terminate()`. Otherwise, has no
927
+ effects.
928
 
929
  [*Note 1*: Either implicitly detaching or joining a `joinable()` thread
930
  in its destructor could result in difficult to debug correctness (for
931
  detach) or performance (for join) bugs encountered only when an
932
  exception is thrown. Thus the programmer must ensure that the destructor
933
  is never executed while the thread is still joinable. — *end note*]
934
 
935
+ #### Assignment <a id="thread.thread.assign">[[thread.thread.assign]]</a>
936
 
937
  ``` cpp
938
  thread& operator=(thread&& x) noexcept;
939
  ```
940
 
941
  *Effects:* If `joinable()`, calls `terminate()`. Otherwise, assigns the
942
  state of `x` to `*this` and sets `x` to a default constructed state.
943
 
944
+ *Ensures:* `x.get_id() == id()` and `get_id()` returns the value of
945
+ `x.get_id()` prior to the assignment.
946
 
947
  *Returns:* `*this`.
948
 
949
+ #### Members <a id="thread.thread.member">[[thread.thread.member]]</a>
950
 
951
  ``` cpp
952
  void swap(thread& x) noexcept;
953
  ```
954
 
 
962
 
963
  ``` cpp
964
  void join();
965
  ```
966
 
967
+ *Effects:* Blocks until the thread represented by `*this` has completed.
 
968
 
969
  *Synchronization:* The completion of the thread represented by `*this`
970
+ synchronizes with [[intro.multithread]] the corresponding successful
971
  `join()` return.
972
 
973
  [*Note 1*: Operations on `*this` are not synchronized. — *end note*]
974
 
975
+ *Ensures:* The thread represented by `*this` has completed.
976
  `get_id() == id()`.
977
 
978
  *Throws:* `system_error` when an exception is
979
+ required [[thread.req.exception]].
980
 
981
  *Error conditions:*
982
 
983
  - `resource_deadlock_would_occur` — if deadlock is detected or
984
  `get_id() == this_thread::get_id()`.
 
991
 
992
  *Effects:* The thread represented by `*this` continues execution without
993
  the calling thread blocking. When `detach()` returns, `*this` no longer
994
  represents the possibly continuing thread of execution. When the thread
995
  previously represented by `*this` ends execution, the implementation
996
+ releases any owned resources.
997
 
998
+ *Ensures:* `get_id() == id()`.
999
 
1000
  *Throws:* `system_error` when an exception is
1001
+ required [[thread.req.exception]].
1002
 
1003
  *Error conditions:*
1004
 
1005
  - `no_such_process` — if the thread is not valid.
1006
  - `invalid_argument` — if the thread is not joinable.
 
1011
 
1012
  *Returns:* A default constructed `id` object if `*this` does not
1013
  represent a thread, otherwise `this_thread::get_id()` for the thread of
1014
  execution represented by `*this`.
1015
 
1016
+ #### Static members <a id="thread.thread.static">[[thread.thread.static]]</a>
1017
 
1018
  ``` cpp
1019
  unsigned hardware_concurrency() noexcept;
1020
  ```
1021
 
1022
  *Returns:* The number of hardware thread contexts.
1023
 
1024
  [*Note 1*: This value should only be considered to be a
1025
  hint. — *end note*]
1026
 
1027
+ If this value is not computable or well-defined, an implementation
1028
+ should return 0.
1029
 
1030
+ #### Specialized algorithms <a id="thread.thread.algorithm">[[thread.thread.algorithm]]</a>
1031
 
1032
  ``` cpp
1033
  void swap(thread& x, thread& y) noexcept;
1034
  ```
1035
 
1036
  *Effects:* As if by `x.swap(y)`.
1037
 
1038
+ ### Class `jthread` <a id="thread.jthread.class">[[thread.jthread.class]]</a>
1039
+
1040
+ The class `jthread` provides a mechanism to create a new thread of
1041
+ execution. The functionality is the same as for class `thread`
1042
+ [[thread.thread.class]] with the additional abilities to provide a
1043
+ `stop_token` [[thread.stoptoken]] to the new thread of execution, make
1044
+ stop requests, and automatically join.
1045
+
1046
+ ``` cpp
1047
+ namespace std {
1048
+ class jthread {
1049
+ public:
1050
+ // types
1051
+ using id = thread::id;
1052
+ using native_handle_type = thread::native_handle_type;
1053
+
1054
+ // [thread.jthread.cons], constructors, move, and assignment
1055
+ jthread() noexcept;
1056
+ template<class F, class... Args> explicit jthread(F&& f, Args&&... args);
1057
+ ~jthread();
1058
+ jthread(const jthread&) = delete;
1059
+ jthread(jthread&&) noexcept;
1060
+ jthread& operator=(const jthread&) = delete;
1061
+ jthread& operator=(jthread&&) noexcept;
1062
+
1063
+ // [thread.jthread.mem], members
1064
+ void swap(jthread&) noexcept;
1065
+ [[nodiscard]] bool joinable() const noexcept;
1066
+ void join();
1067
+ void detach();
1068
+ [[nodiscard]] id get_id() const noexcept;
1069
+ [[nodiscard]] native_handle_type native_handle(); // see~[thread.req.native]
1070
+
1071
+ // [thread.jthread.stop], stop token handling
1072
+ [[nodiscard]] stop_source get_stop_source() noexcept;
1073
+ [[nodiscard]] stop_token get_stop_token() const noexcept;
1074
+ bool request_stop() noexcept;
1075
+
1076
+ // [thread.jthread.special], specialized algorithms
1077
+ friend void swap(jthread& lhs, jthread& rhs) noexcept;
1078
+
1079
+ // [thread.jthread.static], static members
1080
+ [[nodiscard]] static unsigned int hardware_concurrency() noexcept;
1081
+
1082
+ private:
1083
+ stop_source ssource; // exposition only
1084
+ };
1085
+ }
1086
+ ```
1087
+
1088
+ #### Constructors, move, and assignment <a id="thread.jthread.cons">[[thread.jthread.cons]]</a>
1089
+
1090
+ ``` cpp
1091
+ jthread() noexcept;
1092
+ ```
1093
+
1094
+ *Effects:* Constructs a `jthread` object that does not represent a
1095
+ thread of execution.
1096
+
1097
+ *Ensures:* `get_id() == id()` is `true` and `ssource.stop_possible()` is
1098
+ `false`.
1099
+
1100
+ ``` cpp
1101
+ template<class F, class... Args> explicit jthread(F&& f, Args&&... args);
1102
+ ```
1103
+
1104
+ *Constraints:* `remove_cvref_t<F>` is not the same type as `jthread`.
1105
+
1106
+ *Mandates:* The following are all `true`:
1107
+
1108
+ - `is_constructible_v<decay_t<F>, F>`,
1109
+ - `(is_constructible_v<decay_t<Args>, Args> && ...)`,
1110
+ - `is_move_constructible_v<decay_t<F>>`,
1111
+ - `(is_move_constructible_v<decay_t<Args>> && ...)`, and
1112
+ - `is_invocable_v<decay_t<F>, decay_t<Args>...> ||`
1113
+ `is_invocable_v<decay_t<F>, stop_token, decay_t<Args>...>`.
1114
+
1115
+ *Preconditions:* `decay_t<F>` and each type in `decay_t<Args>` meet the
1116
+ *Cpp17MoveConstructible* requirements.
1117
+
1118
+ *Effects:* Initializes `ssource`. The new thread of execution executes
1119
+
1120
+ ``` cpp
1121
+ invoke(decay-copy(std::forward<F>(f)), get_stop_token(),
1122
+ decay-copy(std::forward<Args>(args))...)
1123
+ ```
1124
+
1125
+ if that expression is well-formed, otherwise
1126
+
1127
+ ``` cpp
1128
+ invoke(decay-copy(std::forward<F>(f)), decay-copy(std::forward<Args>(args))...)
1129
+ ```
1130
+
1131
+ with the calls to *`decay-copy`* being evaluated in the constructing
1132
+ thread. Any return value from this invocation is ignored.
1133
+
1134
+ [*Note 1*: This implies that any exceptions not thrown from the
1135
+ invocation of the copy of `f` will be thrown in the constructing thread,
1136
+ not the new thread. — *end note*]
1137
+
1138
+ If the `invoke` expression exits via an exception, `terminate` is
1139
+ called.
1140
+
1141
+ *Synchronization:* The completion of the invocation of the constructor
1142
+ synchronizes with the beginning of the invocation of the copy of `f`.
1143
+
1144
+ *Ensures:* `get_id() != id()` is `true` and `ssource.stop_possible()` is
1145
+ `true` and `*this` represents the newly started thread.
1146
+
1147
+ [*Note 2*: The calling thread can make a stop request only once,
1148
+ because it cannot replace this stop token. — *end note*]
1149
+
1150
+ *Throws:* `system_error` if unable to start the new thread.
1151
+
1152
+ *Error conditions:*
1153
+
1154
+ - `resource_unavailable_try_again` — the system lacked the necessary
1155
+ resources to create another thread, or the system-imposed limit on the
1156
+ number of threads in a process would be exceeded.
1157
+
1158
+ ``` cpp
1159
+ jthread(jthread&& x) noexcept;
1160
+ ```
1161
+
1162
+ *Ensures:* `x.get_id() == id()` and `get_id()` returns the value of
1163
+ `x.get_id()` prior to the start of construction. `ssource` has the value
1164
+ of `x.ssource` prior to the start of construction and
1165
+ `x.ssource.stop_possible()` is `false`.
1166
+
1167
+ ``` cpp
1168
+ ~jthread();
1169
+ ```
1170
+
1171
+ *Effects:* If `joinable()` is `true`, calls `request_stop()` and then
1172
+ `join()`.
1173
+
1174
+ [*Note 3*: Operations on `*this` are not synchronized. — *end note*]
1175
+
1176
+ ``` cpp
1177
+ jthread& operator=(jthread&& x) noexcept;
1178
+ ```
1179
+
1180
+ *Effects:* If `joinable()` is `true`, calls `request_stop()` and then
1181
+ `join()`. Assigns the state of `x` to `*this` and sets `x` to a default
1182
+ constructed state.
1183
+
1184
+ *Ensures:* `x.get_id() == id()` and `get_id()` returns the value of
1185
+ `x.get_id()` prior to the assignment. `ssource` has the value of
1186
+ `x.ssource` prior to the assignment and `x.ssource.stop_possible()` is
1187
+ `false`.
1188
+
1189
+ *Returns:* `*this`.
1190
+
1191
+ #### Members <a id="thread.jthread.mem">[[thread.jthread.mem]]</a>
1192
+
1193
+ ``` cpp
1194
+ void swap(jthread& x) noexcept;
1195
+ ```
1196
+
1197
+ *Effects:* Exchanges the values of `*this` and `x`.
1198
+
1199
+ ``` cpp
1200
+ [[nodiscard]] bool joinable() const noexcept;
1201
+ ```
1202
+
1203
+ *Returns:* `get_id() != id()`.
1204
+
1205
+ ``` cpp
1206
+ void join();
1207
+ ```
1208
+
1209
+ *Effects:* Blocks until the thread represented by `*this` has completed.
1210
+
1211
+ *Synchronization:* The completion of the thread represented by `*this`
1212
+ synchronizes with [[intro.multithread]] the corresponding successful
1213
+ `join()` return.
1214
+
1215
+ [*Note 1*: Operations on `*this` are not synchronized. — *end note*]
1216
+
1217
+ *Ensures:* The thread represented by `*this` has completed.
1218
+ `get_id() == id()`.
1219
+
1220
+ *Throws:* `system_error` when an exception is
1221
+ required [[thread.req.exception]].
1222
+
1223
+ *Error conditions:*
1224
+
1225
+ - `resource_deadlock_would_occur` — if deadlock is detected or
1226
+ `get_id() == this_thread::get_id()`.
1227
+ - `no_such_process` — if the thread is not valid.
1228
+ - `invalid_argument` — if the thread is not joinable.
1229
+
1230
+ ``` cpp
1231
+ void detach();
1232
+ ```
1233
+
1234
+ *Effects:* The thread represented by `*this` continues execution without
1235
+ the calling thread blocking. When `detach()` returns, `*this` no longer
1236
+ represents the possibly continuing thread of execution. When the thread
1237
+ previously represented by `*this` ends execution, the implementation
1238
+ releases any owned resources.
1239
+
1240
+ *Ensures:* `get_id() == id()`.
1241
+
1242
+ *Throws:* `system_error` when an exception is
1243
+ required [[thread.req.exception]].
1244
+
1245
+ *Error conditions:*
1246
+
1247
+ - `no_such_process` — if the thread is not valid.
1248
+ - `invalid_argument` — if the thread is not joinable.
1249
+
1250
+ ``` cpp
1251
+ id get_id() const noexcept;
1252
+ ```
1253
+
1254
+ *Returns:* A default constructed `id` object if `*this` does not
1255
+ represent a thread, otherwise `this_thread::get_id()` for the thread of
1256
+ execution represented by `*this`.
1257
+
1258
+ #### Stop token handling <a id="thread.jthread.stop">[[thread.jthread.stop]]</a>
1259
+
1260
+ ``` cpp
1261
+ [[nodiscard]] stop_source get_stop_source() noexcept;
1262
+ ```
1263
+
1264
+ *Effects:* Equivalent to: `return ssource;`
1265
+
1266
+ ``` cpp
1267
+ [[nodiscard]] stop_token get_stop_token() const noexcept;
1268
+ ```
1269
+
1270
+ *Effects:* Equivalent to: `return ssource.get_token();`
1271
+
1272
+ ``` cpp
1273
+ bool request_stop() noexcept;
1274
+ ```
1275
+
1276
+ *Effects:* Equivalent to: `return ssource.request_stop();`
1277
+
1278
+ #### Specialized algorithms <a id="thread.jthread.special">[[thread.jthread.special]]</a>
1279
+
1280
+ ``` cpp
1281
+ friend void swap(jthread& x, jthread& y) noexcept;
1282
+ ```
1283
+
1284
+ *Effects:* Equivalent to: `x.swap(y)`.
1285
+
1286
+ #### Static members <a id="thread.jthread.static">[[thread.jthread.static]]</a>
1287
+
1288
+ ``` cpp
1289
+ [[nodiscard]] static unsigned int hardware_concurrency() noexcept;
1290
+ ```
1291
+
1292
+ *Returns:* `thread::hardware_concurrency()`.
1293
+
1294
  ### Namespace `this_thread` <a id="thread.thread.this">[[thread.thread.this]]</a>
1295
 
1296
  ``` cpp
1297
  namespace std::this_thread {
1298
  thread::id get_id() noexcept;
 
1308
  ``` cpp
1309
  thread::id this_thread::get_id() noexcept;
1310
  ```
1311
 
1312
  *Returns:* An object of type `thread::id` that uniquely identifies the
1313
+ current thread of execution. No other thread of execution has this id
1314
+ and this thread of execution always has this id. The object returned
1315
+ does not compare equal to a default constructed `thread::id`.
 
1316
 
1317
  ``` cpp
1318
  void this_thread::yield() noexcept;
1319
  ```
1320
 
 
1326
  template<class Clock, class Duration>
1327
  void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
1328
  ```
1329
 
1330
  *Effects:* Blocks the calling thread for the absolute
1331
+ timeout [[thread.req.timing]] specified by `abs_time`.
1332
 
1333
  *Synchronization:* None.
1334
 
1335
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
1336
 
1337
  ``` cpp
1338
  template<class Rep, class Period>
1339
  void sleep_for(const chrono::duration<Rep, Period>& rel_time);
1340
  ```
1341
 
1342
  *Effects:* Blocks the calling thread for the relative
1343
+ timeout [[thread.req.timing]] specified by `rel_time`.
1344
 
1345
  *Synchronization:* None.
1346
 
1347
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
1348
 
1349
  ## Mutual exclusion <a id="thread.mutex">[[thread.mutex]]</a>
1350
 
1351
+ This subclause provides mechanisms for mutual exclusion: mutexes, locks,
1352
  and call once. These mechanisms ease the production of race-free
1353
+ programs [[intro.multithread]].
1354
 
1355
  ### Header `<mutex>` synopsis <a id="mutex.syn">[[mutex.syn]]</a>
1356
 
1357
  ``` cpp
1358
  namespace std {
 
1384
  template<class Callable, class... Args>
1385
  void call_once(once_flag& flag, Callable&& func, Args&&... args);
1386
  }
1387
  ```
1388
 
1389
+ ### Header `<shared_mutex>` synopsis <a id="shared.mutex.syn">[[shared.mutex.syn]]</a>
1390
 
1391
  ``` cpp
1392
  namespace std {
1393
  class shared_mutex;
1394
  class shared_timed_mutex;
 
1401
  ### Mutex requirements <a id="thread.mutex.requirements">[[thread.mutex.requirements]]</a>
1402
 
1403
  #### In general <a id="thread.mutex.requirements.general">[[thread.mutex.requirements.general]]</a>
1404
 
1405
  A mutex object facilitates protection against data races and allows safe
1406
+ synchronization of data between execution agents
1407
+ [[thread.req.lockable]]. An execution agent *owns* a mutex from the time
1408
+ it successfully calls one of the lock functions until it calls unlock.
1409
+ Mutexes can be either recursive or non-recursive, and can grant
1410
  simultaneous ownership to one or many execution agents. Both recursive
1411
  and non-recursive mutexes are supplied.
1412
 
1413
  #### Mutex types <a id="thread.mutex.requirements.mutex">[[thread.mutex.requirements.mutex]]</a>
1414
 
1415
  The *mutex types* are the standard library types `mutex`,
1416
  `recursive_mutex`, `timed_mutex`, `recursive_timed_mutex`,
1417
+ `shared_mutex`, and `shared_timed_mutex`. They meet the requirements set
1418
+ out in this subclause. In this description, `m` denotes an object of a
1419
+ mutex type.
1420
 
1421
+ The mutex types meet the *Cpp17Lockable* requirements
1422
+ [[thread.req.lockable.req]].
1423
 
1424
+ The mutex types meet *Cpp17DefaultConstructible* and
1425
+ *Cpp17Destructible*. If initialization of an object of a mutex type
1426
+ fails, an exception of type `system_error` is thrown. The mutex types
1427
+ are neither copyable nor movable.
1428
 
1429
  The error conditions for error codes, if any, reported by member
1430
+ functions of the mutex types are as follows:
1431
 
1432
  - `resource_unavailable_try_again` — if any native handle type
1433
  manipulated is not available.
1434
  - `operation_not_permitted` — if the thread does not have the privilege
1435
  to perform the operation.
1436
  - `invalid_argument` — if any native handle type manipulated as part of
1437
  mutex construction is incorrect.
1438
 
1439
+ The implementation provides lock and unlock operations, as described
1440
+ below. For purposes of determining the existence of a data race, these
1441
+ behave as atomic operations [[intro.multithread]]. The lock and unlock
1442
+ operations on a single mutex appears to occur in a single total order.
 
1443
 
1444
+ [*Note 1*: This can be viewed as the modification order
1445
+ [[intro.multithread]] of the mutex. — *end note*]
1446
 
1447
  [*Note 2*: Construction and destruction of an object of a mutex type
1448
  need not be thread-safe; other synchronization should be used to ensure
1449
  that mutex objects are initialized and visible to other
1450
  threads. — *end note*]
1451
 
1452
+ The expression `m.lock()` is well-formed and has the following
1453
  semantics:
1454
 
1455
+ *Preconditions:* If `m` is of type `mutex`, `timed_mutex`,
1456
+ `shared_mutex`, or `shared_timed_mutex`, the calling thread does not own
1457
+ the mutex.
1458
 
1459
  *Effects:* Blocks the calling thread until ownership of the mutex can be
1460
  obtained for the calling thread.
1461
 
1462
+ *Ensures:* The calling thread owns the mutex.
1463
 
1464
  *Return type:* `void`.
1465
 
1466
+ *Synchronization:* Prior `unlock()` operations on the same object
1467
+ *synchronize with*[[intro.multithread]] this operation.
1468
 
1469
  *Throws:* `system_error` when an exception is
1470
+ required [[thread.req.exception]].
1471
 
1472
  *Error conditions:*
1473
 
1474
  - `operation_not_permitted` — if the thread does not have the privilege
1475
  to perform the operation.
1476
  - `resource_deadlock_would_occur` — if the implementation detects that a
1477
  deadlock would occur.
1478
 
1479
+ The expression `m.try_lock()` is well-formed and has the following
1480
+ semantics:
1481
 
1482
+ *Preconditions:* If `m` is of type `mutex`, `timed_mutex`,
1483
+ `shared_mutex`, or `shared_timed_mutex`, the calling thread does not own
1484
+ the mutex.
1485
 
1486
  *Effects:* Attempts to obtain ownership of the mutex for the calling
1487
  thread without blocking. If ownership is not obtained, there is no
1488
  effect and `try_lock()` immediately returns. An implementation may fail
1489
  to obtain the lock even if it is not held by any other thread.
1490
 
1491
  [*Note 1*: This spurious failure is normally uncommon, but allows
1492
+ interesting implementations based on a simple compare and
1493
+ exchange [[atomics]]. — *end note*]
1494
 
1495
  An implementation should ensure that `try_lock()` does not consistently
1496
  return `false` in the absence of contending mutex acquisitions.
1497
 
1498
  *Return type:* `bool`.
1499
 
1500
  *Returns:* `true` if ownership of the mutex was obtained for the calling
1501
  thread, otherwise `false`.
1502
 
1503
  *Synchronization:* If `try_lock()` returns `true`, prior `unlock()`
1504
+ operations on the same object *synchronize with*[[intro.multithread]]
1505
+ this operation.
1506
 
1507
  [*Note 2*: Since `lock()` does not synchronize with a failed subsequent
1508
  `try_lock()`, the visibility rules are weak enough that little would be
1509
  known about the state after a failure, even in the absence of spurious
1510
  failures. — *end note*]
1511
 
1512
  *Throws:* Nothing.
1513
 
1514
+ The expression `m.unlock()` is well-formed and has the following
1515
  semantics:
1516
 
1517
+ *Preconditions:* The calling thread owns the mutex.
1518
 
1519
  *Effects:* Releases the calling thread’s ownership of the mutex.
1520
 
1521
  *Return type:* `void`.
1522
 
1523
  *Synchronization:* This operation synchronizes
1524
+ with [[intro.multithread]] subsequent lock operations that obtain
1525
  ownership on the same object.
1526
 
1527
  *Throws:* Nothing.
1528
 
1529
  ##### Class `mutex` <a id="thread.mutex.class">[[thread.mutex.class]]</a>
 
1540
 
1541
  void lock();
1542
  bool try_lock();
1543
  void unlock();
1544
 
1545
+ using native_handle_type = implementation-defined; // see~[thread.req.native]
1546
+ native_handle_type native_handle(); // see~[thread.req.native]
1547
  };
1548
  }
1549
  ```
1550
 
1551
  The class `mutex` provides a non-recursive mutex with exclusive
 
1561
  required to handle such scenarios correctly, as long as thread `A`
1562
  doesn’t access the mutex after the unlock call returns. These cases
1563
  typically occur when a reference-counted object contains a mutex that is
1564
  used to protect the reference count. — *end note*]
1565
 
1566
+ The class `mutex` meets all of the mutex requirements
1567
+ [[thread.mutex.requirements]]. It is a standard-layout class
1568
+ [[class.prop]].
1569
 
1570
+ [*Note 4*: A program can deadlock if the thread that owns a `mutex`
1571
  object calls `lock()` on that object. If the implementation can detect
1572
+ the deadlock, a `resource_deadlock_would_occur` error condition might be
1573
  observed. — *end note*]
1574
 
1575
  The behavior of a program is undefined if it destroys a `mutex` object
1576
  owned by any thread or a thread terminates while owning a `mutex`
1577
  object.
 
1590
 
1591
  void lock();
1592
  bool try_lock() noexcept;
1593
  void unlock();
1594
 
1595
+ using native_handle_type = implementation-defined; // see~[thread.req.native]
1596
+ native_handle_type native_handle(); // see~[thread.req.native]
1597
  };
1598
  }
1599
  ```
1600
 
1601
  The class `recursive_mutex` provides a recursive mutex with exclusive
1602
  ownership semantics. If one thread owns a `recursive_mutex` object,
1603
  attempts by another thread to acquire ownership of that object will fail
1604
  (for `try_lock()`) or block (for `lock()`) until the first thread has
1605
  completely released ownership.
1606
 
1607
+ The class `recursive_mutex` meets all of the mutex requirements
1608
+ [[thread.mutex.requirements]]. It is a standard-layout class
1609
+ [[class.prop]].
1610
 
1611
  A thread that owns a `recursive_mutex` object may acquire additional
1612
  levels of ownership by calling `lock()` or `try_lock()` on that object.
1613
  It is unspecified how many levels of ownership may be acquired by a
1614
  single thread. If a thread has already acquired the maximum level of
1615
  ownership for a `recursive_mutex` object, additional calls to
1616
+ `try_lock()` fail, and additional calls to `lock()` throw an exception
1617
+ of type `system_error`. A thread shall call `unlock()` once for each
1618
+ level of ownership acquired by calls to `lock()` and `try_lock()`. Only
1619
+ when all levels of ownership have been released may ownership be
1620
+ acquired by another thread.
1621
 
1622
  The behavior of a program is undefined if:
1623
 
1624
  - it destroys a `recursive_mutex` object owned by any thread or
1625
  - a thread terminates while owning a `recursive_mutex` object.
1626
 
1627
  #### Timed mutex types <a id="thread.timedmutex.requirements">[[thread.timedmutex.requirements]]</a>
1628
 
1629
  The *timed mutex types* are the standard library types `timed_mutex`,
1630
+ `recursive_timed_mutex`, and `shared_timed_mutex`. They meet the
1631
  requirements set out below. In this description, `m` denotes an object
1632
  of a mutex type, `rel_time` denotes an object of an instantiation of
1633
+ `duration` [[time.duration]], and `abs_time` denotes an object of an
1634
+ instantiation of `time_point` [[time.point]].
1635
 
1636
+ The timed mutex types meet the *Cpp17TimedLockable* requirements
1637
+ [[thread.req.lockable.timed]].
1638
 
1639
+ The expression `m.try_lock_for(rel_time)` is well-formed and has the
1640
+ following semantics:
1641
 
1642
+ *Preconditions:* If `m` is of type `timed_mutex` or
1643
+ `shared_timed_mutex`, the calling thread does not own the mutex.
1644
 
1645
  *Effects:* The function attempts to obtain ownership of the mutex within
1646
+ the relative timeout [[thread.req.timing]] specified by `rel_time`. If
1647
+ the time specified by `rel_time` is less than or equal to
1648
  `rel_time.zero()`, the function attempts to obtain ownership without
1649
+ blocking (as if by calling `try_lock()`). The function returns within
1650
+ the timeout specified by `rel_time` only if it has obtained ownership of
1651
+ the mutex object.
1652
 
1653
  [*Note 1*: As with `try_lock()`, there is no guarantee that ownership
1654
  will be obtained if the lock is available, but implementations are
1655
  expected to make a strong effort to do so. — *end note*]
1656
 
1657
  *Return type:* `bool`.
1658
 
1659
  *Returns:* `true` if ownership was obtained, otherwise `false`.
1660
 
1661
  *Synchronization:* If `try_lock_for()` returns `true`, prior `unlock()`
1662
+ operations on the same object *synchronize with*[[intro.multithread]]
1663
+ this operation.
1664
 
1665
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
1666
 
1667
+ The expression `m.try_lock_until(abs_time)` is well-formed and has the
1668
+ following semantics:
1669
 
1670
+ *Preconditions:* If `m` is of type `timed_mutex` or
1671
+ `shared_timed_mutex`, the calling thread does not own the mutex.
1672
 
1673
  *Effects:* The function attempts to obtain ownership of the mutex. If
1674
  `abs_time` has already passed, the function attempts to obtain ownership
1675
+ without blocking (as if by calling `try_lock()`). The function returns
1676
+ before the absolute timeout [[thread.req.timing]] specified by
1677
  `abs_time` only if it has obtained ownership of the mutex object.
1678
 
1679
  [*Note 2*: As with `try_lock()`, there is no guarantee that ownership
1680
  will be obtained if the lock is available, but implementations are
1681
  expected to make a strong effort to do so. — *end note*]
 
1684
 
1685
  *Returns:* `true` if ownership was obtained, otherwise `false`.
1686
 
1687
  *Synchronization:* If `try_lock_until()` returns `true`, prior
1688
  `unlock()` operations on the same object *synchronize
1689
+ with*[[intro.multithread]] this operation.
1690
 
1691
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
1692
 
1693
  ##### Class `timed_mutex` <a id="thread.timedmutex.class">[[thread.timedmutex.class]]</a>
1694
 
1695
  ``` cpp
1696
  namespace std {
 
1708
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
1709
  template<class Clock, class Duration>
1710
  bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
1711
  void unlock();
1712
 
1713
+ using native_handle_type = implementation-defined; // see~[thread.req.native]
1714
+ native_handle_type native_handle(); // see~[thread.req.native]
1715
  };
1716
  }
1717
  ```
1718
 
1719
  The class `timed_mutex` provides a non-recursive mutex with exclusive
 
1722
  `try_lock()`) or block (for `lock()`, `try_lock_for()`, and
1723
  `try_lock_until()`) until the owning thread has released ownership with
1724
  a call to `unlock()` or the call to `try_lock_for()` or
1725
  `try_lock_until()` times out (having failed to obtain ownership).
1726
 
1727
+ The class `timed_mutex` meets all of the timed mutex requirements
1728
+ [[thread.timedmutex.requirements]]. It is a standard-layout class
1729
+ [[class.prop]].
1730
 
1731
  The behavior of a program is undefined if:
1732
 
1733
  - it destroys a `timed_mutex` object owned by any thread,
1734
  - a thread that owns a `timed_mutex` object calls `lock()`,
 
1754
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
1755
  template<class Clock, class Duration>
1756
  bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
1757
  void unlock();
1758
 
1759
+ using native_handle_type = implementation-defined; // see~[thread.req.native]
1760
+ native_handle_type native_handle(); // see~[thread.req.native]
1761
  };
1762
  }
1763
  ```
1764
 
1765
  The class `recursive_timed_mutex` provides a recursive mutex with
 
1768
  ownership of that object will fail (for `try_lock()`) or block (for
1769
  `lock()`, `try_lock_for()`, and `try_lock_until()`) until the owning
1770
  thread has completely released ownership or the call to `try_lock_for()`
1771
  or `try_lock_until()` times out (having failed to obtain ownership).
1772
 
1773
+ The class `recursive_timed_mutex` meets all of the timed mutex
1774
+ requirements [[thread.timedmutex.requirements]]. It is a standard-layout
1775
+ class [[class.prop]].
1776
 
1777
  A thread that owns a `recursive_timed_mutex` object may acquire
1778
  additional levels of ownership by calling `lock()`, `try_lock()`,
1779
  `try_lock_for()`, or `try_lock_until()` on that object. It is
1780
  unspecified how many levels of ownership may be acquired by a single
1781
  thread. If a thread has already acquired the maximum level of ownership
1782
  for a `recursive_timed_mutex` object, additional calls to `try_lock()`,
1783
+ `try_lock_for()`, or `try_lock_until()` fail, and additional calls to
1784
+ `lock()` throw an exception of type `system_error`. A thread shall call
1785
+ `unlock()` once for each level of ownership acquired by calls to
1786
+ `lock()`, `try_lock()`, `try_lock_for()`, and `try_lock_until()`. Only
1787
+ when all levels of ownership have been released may ownership of the
1788
+ object be acquired by another thread.
1789
 
1790
  The behavior of a program is undefined if:
1791
 
1792
  - it destroys a `recursive_timed_mutex` object owned by any thread, or
1793
  - a thread terminates while owning a `recursive_timed_mutex` object.
1794
 
1795
  #### Shared mutex types <a id="thread.sharedmutex.requirements">[[thread.sharedmutex.requirements]]</a>
1796
 
1797
  The standard library types `shared_mutex` and `shared_timed_mutex` are
1798
+ *shared mutex types*. Shared mutex types meet the requirements of mutex
1799
+ types [[thread.mutex.requirements.mutex]] and additionally meet the
1800
+ requirements set out below. In this description, `m` denotes an object
1801
+ of a shared mutex type.
1802
 
1803
  In addition to the exclusive lock ownership mode specified in 
1804
  [[thread.mutex.requirements.mutex]], shared mutex types provide a
1805
  *shared lock* ownership mode. Multiple execution agents can
1806
  simultaneously hold a shared lock ownership of a shared mutex type. But
1807
+ no execution agent holds a shared lock while another execution agent
1808
+ holds an exclusive lock on the same shared mutex type, and vice-versa.
1809
+ The maximum number of execution agents which can share a shared lock on
1810
+ a single shared mutex type is unspecified, but is at least 10000. If
1811
+ more than the maximum number of execution agents attempt to obtain a
1812
+ shared lock, the excess execution agents block until the number of
1813
+ shared locks are reduced below the maximum amount by other execution
1814
+ agents releasing their shared lock.
1815
 
1816
+ The expression `m.lock_shared()` is well-formed and has the following
1817
+ semantics:
1818
 
1819
+ *Preconditions:* The calling thread has no ownership of the mutex.
1820
 
1821
  *Effects:* Blocks the calling thread until shared ownership of the mutex
1822
  can be obtained for the calling thread. If an exception is thrown then a
1823
+ shared lock has not been acquired for the current thread.
1824
 
1825
+ *Ensures:* The calling thread has a shared lock on the mutex.
1826
 
1827
  *Return type:* `void`.
1828
 
1829
+ *Synchronization:* Prior `unlock()` operations on the same object
1830
+ synchronize with [[intro.multithread]] this operation.
1831
 
1832
  *Throws:* `system_error` when an exception is
1833
+ required [[thread.req.exception]].
1834
 
1835
  *Error conditions:*
1836
 
1837
  - `operation_not_permitted` — if the thread does not have the privilege
1838
  to perform the operation.
1839
  - `resource_deadlock_would_occur` — if the implementation detects that a
1840
  deadlock would occur.
1841
 
1842
+ The expression `m.unlock_shared()` is well-formed and has the following
1843
+ semantics:
1844
 
1845
+ *Preconditions:* The calling thread holds a shared lock on the mutex.
1846
 
1847
  *Effects:* Releases a shared lock on the mutex held by the calling
1848
  thread.
1849
 
1850
  *Return type:* `void`.
1851
 
1852
  *Synchronization:* This operation synchronizes
1853
+ with [[intro.multithread]] subsequent `lock()` operations that obtain
1854
  ownership on the same object.
1855
 
1856
  *Throws:* Nothing.
1857
 
1858
+ The expression `m.try_lock_shared()` is well-formed and has the
1859
  following semantics:
1860
 
1861
+ *Preconditions:* The calling thread has no ownership of the mutex.
1862
 
1863
  *Effects:* Attempts to obtain shared ownership of the mutex for the
1864
  calling thread without blocking. If shared ownership is not obtained,
1865
  there is no effect and `try_lock_shared()` immediately returns. An
1866
  implementation may fail to obtain the lock even if it is not held by any
 
1871
  *Returns:* `true` if the shared ownership lock was acquired, `false`
1872
  otherwise.
1873
 
1874
  *Synchronization:* If `try_lock_shared()` returns `true`, prior
1875
  `unlock()` operations on the same object synchronize
1876
+ with [[intro.multithread]] this operation.
1877
 
1878
  *Throws:* Nothing.
1879
 
1880
+ ##### Class `shared_mutex` <a id="thread.sharedmutex.class">[[thread.sharedmutex.class]]</a>
1881
 
1882
  ``` cpp
1883
  namespace std {
1884
  class shared_mutex {
1885
  public:
 
1887
  ~shared_mutex();
1888
 
1889
  shared_mutex(const shared_mutex&) = delete;
1890
  shared_mutex& operator=(const shared_mutex&) = delete;
1891
 
1892
+ // exclusive ownership
1893
  void lock(); // blocking
1894
  bool try_lock();
1895
  void unlock();
1896
 
1897
+ // shared ownership
1898
  void lock_shared(); // blocking
1899
  bool try_lock_shared();
1900
  void unlock_shared();
1901
 
1902
+ using native_handle_type = implementation-defined; // see~[thread.req.native]
1903
+ native_handle_type native_handle(); // see~[thread.req.native]
1904
  };
1905
  }
1906
  ```
1907
 
1908
  The class `shared_mutex` provides a non-recursive mutex with shared
1909
  ownership semantics.
1910
 
1911
+ The class `shared_mutex` meets all of the shared mutex requirements
1912
+ [[thread.sharedmutex.requirements]]. It is a standard-layout class
1913
+ [[class.prop]].
1914
 
1915
  The behavior of a program is undefined if:
1916
 
1917
  - it destroys a `shared_mutex` object owned by any thread,
1918
  - a thread attempts to recursively gain any ownership of a
 
1923
  `shared_mutex` may be a synonym for `shared_timed_mutex`.
1924
 
1925
  #### Shared timed mutex types <a id="thread.sharedtimedmutex.requirements">[[thread.sharedtimedmutex.requirements]]</a>
1926
 
1927
  The standard library type `shared_timed_mutex` is a *shared timed mutex
1928
+ type*. Shared timed mutex types meet the requirements of timed mutex
1929
+ types [[thread.timedmutex.requirements]], shared mutex types
1930
+ [[thread.sharedmutex.requirements]], and additionally meet the
1931
  requirements set out below. In this description, `m` denotes an object
1932
  of a shared timed mutex type, `rel_type` denotes an object of an
1933
+ instantiation of `duration` [[time.duration]], and `abs_time` denotes an
1934
+ object of an instantiation of `time_point` [[time.point]].
1935
 
1936
+ The expression `m.try_lock_shared_for(rel_time)` is well-formed and has
1937
+ the following semantics:
1938
 
1939
+ *Preconditions:* The calling thread has no ownership of the mutex.
1940
 
1941
  *Effects:* Attempts to obtain shared lock ownership for the calling
1942
+ thread within the relative timeout [[thread.req.timing]] specified by
1943
  `rel_time`. If the time specified by `rel_time` is less than or equal to
1944
  `rel_time.zero()`, the function attempts to obtain ownership without
1945
+ blocking (as if by calling `try_lock_shared()`). The function returns
1946
+ within the timeout specified by `rel_time` only if it has obtained
1947
+ shared ownership of the mutex object.
1948
 
1949
  [*Note 1*: As with `try_lock()`, there is no guarantee that ownership
1950
  will be obtained if the lock is available, but implementations are
1951
  expected to make a strong effort to do so. — *end note*]
1952
 
1953
+ If an exception is thrown then a shared lock has not been acquired for
1954
+ the current thread.
1955
 
1956
  *Return type:* `bool`.
1957
 
1958
  *Returns:* `true` if the shared lock was acquired, `false` otherwise.
1959
 
1960
  *Synchronization:* If `try_lock_shared_for()` returns `true`, prior
1961
  `unlock()` operations on the same object synchronize
1962
+ with [[intro.multithread]] this operation.
1963
 
1964
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
1965
 
1966
+ The expression `m.try_lock_shared_until(abs_time)` is well-formed and
1967
+ has the following semantics:
1968
 
1969
+ *Preconditions:* The calling thread has no ownership of the mutex.
1970
 
1971
  *Effects:* The function attempts to obtain shared ownership of the
1972
  mutex. If `abs_time` has already passed, the function attempts to obtain
1973
  shared ownership without blocking (as if by calling
1974
+ `try_lock_shared()`). The function returns before the absolute
1975
+ timeout [[thread.req.timing]] specified by `abs_time` only if it has
1976
  obtained shared ownership of the mutex object.
1977
 
1978
  [*Note 2*: As with `try_lock()`, there is no guarantee that ownership
1979
  will be obtained if the lock is available, but implementations are
1980
  expected to make a strong effort to do so. — *end note*]
1981
 
1982
+ If an exception is thrown then a shared lock has not been acquired for
1983
+ the current thread.
1984
 
1985
  *Return type:* `bool`.
1986
 
1987
  *Returns:* `true` if the shared lock was acquired, `false` otherwise.
1988
 
1989
  *Synchronization:* If `try_lock_shared_until()` returns `true`, prior
1990
  `unlock()` operations on the same object synchronize
1991
+ with [[intro.multithread]] this operation.
1992
 
1993
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
1994
 
1995
  ##### Class `shared_timed_mutex` <a id="thread.sharedtimedmutex.class">[[thread.sharedtimedmutex.class]]</a>
1996
 
1997
  ``` cpp
1998
  namespace std {
 
2002
  ~shared_timed_mutex();
2003
 
2004
  shared_timed_mutex(const shared_timed_mutex&) = delete;
2005
  shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;
2006
 
2007
+ // exclusive ownership
2008
  void lock(); // blocking
2009
  bool try_lock();
2010
  template<class Rep, class Period>
2011
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
2012
  template<class Clock, class Duration>
2013
  bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
2014
  void unlock();
2015
 
2016
+ // shared ownership
2017
  void lock_shared(); // blocking
2018
  bool try_lock_shared();
2019
  template<class Rep, class Period>
2020
+ bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time);
 
2021
  template<class Clock, class Duration>
2022
+ bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time);
 
2023
  void unlock_shared();
2024
  };
2025
  }
2026
  ```
2027
 
2028
  The class `shared_timed_mutex` provides a non-recursive mutex with
2029
  shared ownership semantics.
2030
 
2031
+ The class `shared_timed_mutex` meets all of the shared timed mutex
2032
+ requirements [[thread.sharedtimedmutex.requirements]]. It is a
2033
+ standard-layout class [[class.prop]].
2034
 
2035
  The behavior of a program is undefined if:
2036
 
2037
  - it destroys a `shared_timed_mutex` object owned by any thread,
2038
  - a thread attempts to recursively gain any ownership of a
 
2088
  lock_guard& operator=(const lock_guard&) = delete;
2089
 
2090
  private:
2091
  mutex_type& pm; // exposition only
2092
  };
 
 
2093
  }
2094
  ```
2095
 
2096
  An object of type `lock_guard` controls the ownership of a lockable
2097
  object within a scope. A `lock_guard` object maintains ownership of a
2098
+ lockable object throughout the `lock_guard` object’s lifetime
2099
+ [[basic.life]]. The behavior of a program is undefined if the lockable
2100
  object referenced by `pm` does not exist for the entire lifetime of the
2101
  `lock_guard` object. The supplied `Mutex` type shall meet the
2102
+ *Cpp17BasicLockable* requirements [[thread.req.lockable.basic]].
2103
 
2104
  ``` cpp
2105
  explicit lock_guard(mutex_type& m);
2106
  ```
2107
 
2108
+ *Preconditions:* If `mutex_type` is not a recursive mutex, the calling
2109
+ thread does not own the mutex `m`.
2110
 
2111
+ *Effects:* Initializes `pm` with `m`. Calls `m.lock()`.
 
 
2112
 
2113
  ``` cpp
2114
  lock_guard(mutex_type& m, adopt_lock_t);
2115
  ```
2116
 
2117
+ *Preconditions:* The calling thread owns the mutex `m`.
2118
 
2119
+ *Effects:* Initializes `pm` with `m`.
2120
 
2121
  *Throws:* Nothing.
2122
 
2123
  ``` cpp
2124
  ~lock_guard();
 
2134
  class scoped_lock {
2135
  public:
2136
  using mutex_type = Mutex; // If MutexTypes... consists of the single type Mutex
2137
 
2138
  explicit scoped_lock(MutexTypes&... m);
2139
+ explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
2140
  ~scoped_lock();
2141
 
2142
  scoped_lock(const scoped_lock&) = delete;
2143
  scoped_lock& operator=(const scoped_lock&) = delete;
2144
 
2145
  private:
2146
  tuple<MutexTypes&...> pm; // exposition only
2147
  };
 
 
 
2148
  }
2149
  ```
2150
 
2151
  An object of type `scoped_lock` controls the ownership of lockable
2152
  objects within a scope. A `scoped_lock` object maintains ownership of
2153
+ lockable objects throughout the `scoped_lock` object’s lifetime
2154
+ [[basic.life]]. The behavior of a program is undefined if the lockable
2155
  objects referenced by `pm` do not exist for the entire lifetime of the
2156
  `scoped_lock` object. When `sizeof...(MutexTypes)` is `1`, the supplied
2157
+ `Mutex` type shall meet the *Cpp17BasicLockable* requirements
2158
+ [[thread.req.lockable.basic]]. Otherwise, each of the mutex types shall
2159
+ meet the *Cpp17Lockable* requirements [[thread.req.lockable.req]].
2160
 
2161
  ``` cpp
2162
  explicit scoped_lock(MutexTypes&... m);
2163
  ```
2164
 
2165
+ *Preconditions:* If a `MutexTypes` type is not a recursive mutex, the
2166
+ calling thread does not own the corresponding mutex element of `m`.
2167
 
2168
  *Effects:* Initializes `pm` with `tie(m...)`. Then if
2169
  `sizeof...(MutexTypes)` is `0`, no effects. Otherwise if
2170
  `sizeof...(MutexTypes)` is `1`, then `m.lock()`. Otherwise,
2171
  `lock(m...)`.
2172
 
2173
  ``` cpp
2174
+ explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
2175
  ```
2176
 
2177
+ *Preconditions:* The calling thread owns all the mutexes in `m`.
2178
 
2179
  *Effects:* Initializes `pm` with `tie(m...)`.
2180
 
2181
  *Throws:* Nothing.
2182
 
 
2237
  private:
2238
  mutex_type* pm; // exposition only
2239
  bool owns; // exposition only
2240
  };
2241
 
 
 
2242
  template<class Mutex>
2243
  void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
2244
  }
2245
  ```
2246
 
 
2249
  at construction or after construction, and may be transferred, after
2250
  acquisition, to another `unique_lock` object. Objects of type
2251
  `unique_lock` are not copyable but are movable. The behavior of a
2252
  program is undefined if the contained pointer `pm` is not null and the
2253
  lockable object pointed to by `pm` does not exist for the entire
2254
+ remaining lifetime [[basic.life]] of the `unique_lock` object. The
2255
+ supplied `Mutex` type shall meet the *Cpp17BasicLockable* requirements
2256
+ [[thread.req.lockable.basic]].
2257
 
2258
+ [*Note 1*: `unique_lock<Mutex>` meets the *Cpp17BasicLockable*
2259
+ requirements. If `Mutex` meets the *Cpp17Lockable* requirements
2260
+ [[thread.req.lockable.req]], `unique_lock<Mutex>` also meets the
2261
+ *Cpp17Lockable* requirements; if `Mutex` meets the *Cpp17TimedLockable*
2262
+ requirements [[thread.req.lockable.timed]], `unique_lock<Mutex>` also
2263
+ meets the *Cpp17TimedLockable* requirements. — *end note*]
2264
 
2265
+ ##### Constructors, destructor, and assignment <a id="thread.lock.unique.cons">[[thread.lock.unique.cons]]</a>
2266
 
2267
  ``` cpp
2268
  unique_lock() noexcept;
2269
  ```
2270
 
2271
+ *Ensures:* `pm == 0` and `owns == false`.
 
 
2272
 
2273
  ``` cpp
2274
  explicit unique_lock(mutex_type& m);
2275
  ```
2276
 
2277
+ *Preconditions:* If `mutex_type` is not a recursive mutex the calling
2278
+ thread does not own the mutex.
2279
 
2280
+ *Effects:* Calls `m.lock()`.
 
2281
 
2282
+ *Ensures:* `pm == addressof(m)` and `owns == true`.
2283
 
2284
  ``` cpp
2285
  unique_lock(mutex_type& m, defer_lock_t) noexcept;
2286
  ```
2287
 
2288
+ *Ensures:* `pm == addressof(m)` and `owns == false`.
 
 
2289
 
2290
  ``` cpp
2291
  unique_lock(mutex_type& m, try_to_lock_t);
2292
  ```
2293
 
2294
+ *Preconditions:* The supplied `Mutex` type meets the *Cpp17Lockable*
2295
+ requirements [[thread.req.lockable.req]]. If `mutex_type` is not a
2296
  recursive mutex the calling thread does not own the mutex.
2297
 
2298
+ *Effects:* Calls `m.try_lock()`.
 
2299
 
2300
+ *Ensures:* `pm == addressof(m)` and `owns == res`, where `res` is the
2301
+ value returned by the call to `m.try_lock()`.
2302
 
2303
  ``` cpp
2304
  unique_lock(mutex_type& m, adopt_lock_t);
2305
  ```
2306
 
2307
+ *Preconditions:* The calling thread owns the mutex.
2308
 
2309
+ *Ensures:* `pm == addressof(m)` and `owns == true`.
 
 
2310
 
2311
  *Throws:* Nothing.
2312
 
2313
  ``` cpp
2314
  template<class Clock, class Duration>
2315
  unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
2316
  ```
2317
 
2318
+ *Preconditions:* If `mutex_type` is not a recursive mutex the calling
2319
+ thread does not own the mutex. The supplied `Mutex` type meets the
2320
+ *Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
2321
 
2322
+ *Effects:* Calls `m.try_lock_until(abs_time)`.
 
2323
 
2324
+ *Ensures:* `pm == addressof(m)` and `owns == res`, where `res` is the
2325
+ value returned by the call to `m.try_lock_until(abs_time)`.
2326
 
2327
  ``` cpp
2328
  template<class Rep, class Period>
2329
  unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
2330
  ```
2331
 
2332
+ *Preconditions:* If `mutex_type` is not a recursive mutex the calling
2333
+ thread does not own the mutex. The supplied `Mutex` type meets the
2334
+ *Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
2335
 
2336
+ *Effects:* Calls `m.try_lock_for(rel_time)`.
 
2337
 
2338
+ *Ensures:* `pm == addressof(m)` and `owns == res`, where `res` is the
2339
+ value returned by the call to `m.try_lock_for(rel_time)`.
2340
 
2341
  ``` cpp
2342
  unique_lock(unique_lock&& u) noexcept;
2343
  ```
2344
 
2345
+ *Ensures:* `pm == u_p.pm` and `owns == u_p.owns` (where `u_p` is the
2346
+ state of `u` just prior to this construction), `u.pm == 0` and
2347
  `u.owns == false`.
2348
 
2349
  ``` cpp
2350
  unique_lock& operator=(unique_lock&& u);
2351
  ```
2352
 
2353
  *Effects:* If `owns` calls `pm->unlock()`.
2354
 
2355
+ *Ensures:* `pm == u_p.pm` and `owns == u_p.owns` (where `u_p` is the
2356
+ state of `u` just prior to this construction), `u.pm == 0` and
2357
  `u.owns == false`.
2358
 
2359
  [*Note 1*: With a recursive mutex it is possible for both `*this` and
2360
  `u` to own the same mutex before the assignment. In this case, `*this`
2361
  will own the mutex after the assignment and `u` will not. — *end note*]
 
2366
  ~unique_lock();
2367
  ```
2368
 
2369
  *Effects:* If `owns` calls `pm->unlock()`.
2370
 
2371
+ ##### Locking <a id="thread.lock.unique.locking">[[thread.lock.unique.locking]]</a>
2372
 
2373
  ``` cpp
2374
  void lock();
2375
  ```
2376
 
2377
  *Effects:* As if by `pm->lock()`.
2378
 
2379
+ *Ensures:* `owns == true`.
2380
 
2381
  *Throws:* Any exception thrown by `pm->lock()`. `system_error` when an
2382
+ exception is required [[thread.req.exception]].
2383
 
2384
  *Error conditions:*
2385
 
2386
  - `operation_not_permitted` — if `pm` is `nullptr`.
2387
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
2388
 
2389
  ``` cpp
2390
  bool try_lock();
2391
  ```
2392
 
2393
+ *Preconditions:* The supplied `Mutex` meets the *Cpp17Lockable*
2394
+ requirements [[thread.req.lockable.req]].
2395
 
2396
  *Effects:* As if by `pm->try_lock()`.
2397
 
2398
  *Returns:* The value returned by the call to `try_lock()`.
2399
 
2400
+ *Ensures:* `owns == res`, where `res` is the value returned by the call
2401
+ to `try_lock()`.
2402
 
2403
  *Throws:* Any exception thrown by `pm->try_lock()`. `system_error` when
2404
+ an exception is required [[thread.req.exception]].
2405
 
2406
  *Error conditions:*
2407
 
2408
  - `operation_not_permitted` — if `pm` is `nullptr`.
2409
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
 
2411
  ``` cpp
2412
  template<class Clock, class Duration>
2413
  bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
2414
  ```
2415
 
2416
+ *Preconditions:* The supplied `Mutex` type meets the
2417
+ *Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
2418
 
2419
  *Effects:* As if by `pm->try_lock_until(abs_time)`.
2420
 
2421
  *Returns:* The value returned by the call to `try_lock_until(abs_time)`.
2422
 
2423
+ *Ensures:* `owns == res`, where `res` is the value returned by the call
2424
+ to `try_lock_until(abs_time)`.
2425
 
2426
  *Throws:* Any exception thrown by `pm->try_lock_until()`. `system_error`
2427
+ when an exception is required [[thread.req.exception]].
2428
 
2429
  *Error conditions:*
2430
 
2431
  - `operation_not_permitted` — if `pm` is `nullptr`.
2432
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
 
2434
  ``` cpp
2435
  template<class Rep, class Period>
2436
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
2437
  ```
2438
 
2439
+ *Preconditions:* The supplied `Mutex` type meets the
2440
+ *Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
2441
 
2442
  *Effects:* As if by `pm->try_lock_for(rel_time)`.
2443
 
2444
+ *Returns:* The value returned by the call to `try_lock_for(rel_time)`.
2445
 
2446
+ *Ensures:* `owns == res`, where `res` is the value returned by the call
2447
+ to `try_lock_for(rel_time)`.
2448
 
2449
  *Throws:* Any exception thrown by `pm->try_lock_for()`. `system_error`
2450
+ when an exception is required [[thread.req.exception]].
2451
 
2452
  *Error conditions:*
2453
 
2454
  - `operation_not_permitted` — if `pm` is `nullptr`.
2455
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
 
2458
  void unlock();
2459
  ```
2460
 
2461
  *Effects:* As if by `pm->unlock()`.
2462
 
2463
+ *Ensures:* `owns == false`.
2464
 
2465
  *Throws:* `system_error` when an exception is
2466
+ required [[thread.req.exception]].
2467
 
2468
  *Error conditions:*
2469
 
2470
  - `operation_not_permitted` — if on entry `owns` is `false`.
2471
 
2472
+ ##### Modifiers <a id="thread.lock.unique.mod">[[thread.lock.unique.mod]]</a>
2473
 
2474
  ``` cpp
2475
  void swap(unique_lock& u) noexcept;
2476
  ```
2477
 
 
2481
  mutex_type* release() noexcept;
2482
  ```
2483
 
2484
  *Returns:* The previous value of `pm`.
2485
 
2486
+ *Ensures:* `pm == 0` and `owns == false`.
2487
 
2488
  ``` cpp
2489
  template<class Mutex>
2490
  void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
2491
  ```
2492
 
2493
  *Effects:* As if by `x.swap(y)`.
2494
 
2495
+ ##### Observers <a id="thread.lock.unique.obs">[[thread.lock.unique.obs]]</a>
2496
 
2497
  ``` cpp
2498
  bool owns_lock() const noexcept;
2499
  ```
2500
 
 
2526
  explicit shared_lock(mutex_type& m); // blocking
2527
  shared_lock(mutex_type& m, defer_lock_t) noexcept;
2528
  shared_lock(mutex_type& m, try_to_lock_t);
2529
  shared_lock(mutex_type& m, adopt_lock_t);
2530
  template<class Clock, class Duration>
2531
+ shared_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
 
2532
  template<class Rep, class Period>
2533
+ shared_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
 
2534
  ~shared_lock();
2535
 
2536
  shared_lock(const shared_lock&) = delete;
2537
  shared_lock& operator=(const shared_lock&) = delete;
2538
 
 
2560
  private:
2561
  mutex_type* pm; // exposition only
2562
  bool owns; // exposition only
2563
  };
2564
 
 
 
2565
  template<class Mutex>
2566
  void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
2567
  }
2568
  ```
2569
 
 
2572
  may be acquired at construction or after construction, and may be
2573
  transferred, after acquisition, to another `shared_lock` object. Objects
2574
  of type `shared_lock` are not copyable but are movable. The behavior of
2575
  a program is undefined if the contained pointer `pm` is not null and the
2576
  lockable object pointed to by `pm` does not exist for the entire
2577
+ remaining lifetime [[basic.life]] of the `shared_lock` object. The
2578
+ supplied `Mutex` type shall meet the shared mutex requirements
2579
+ [[thread.sharedtimedmutex.requirements]].
2580
 
2581
+ [*Note 1*: `shared_lock<Mutex>` meets the *Cpp17TimedLockable*
2582
+ requirements [[thread.req.lockable.timed]]. — *end note*]
2583
 
2584
+ ##### Constructors, destructor, and assignment <a id="thread.lock.shared.cons">[[thread.lock.shared.cons]]</a>
2585
 
2586
  ``` cpp
2587
  shared_lock() noexcept;
2588
  ```
2589
 
2590
+ *Ensures:* `pm == nullptr` and `owns == false`.
 
 
2591
 
2592
  ``` cpp
2593
  explicit shared_lock(mutex_type& m);
2594
  ```
2595
 
2596
+ *Preconditions:* The calling thread does not own the mutex for any
2597
+ ownership mode.
2598
 
2599
+ *Effects:* Calls `m.lock_shared()`.
 
2600
 
2601
+ *Ensures:* `pm == addressof(m)` and `owns == true`.
2602
 
2603
  ``` cpp
2604
  shared_lock(mutex_type& m, defer_lock_t) noexcept;
2605
  ```
2606
 
2607
+ *Ensures:* `pm == addressof(m)` and `owns == false`.
 
 
2608
 
2609
  ``` cpp
2610
  shared_lock(mutex_type& m, try_to_lock_t);
2611
  ```
2612
 
2613
+ *Preconditions:* The calling thread does not own the mutex for any
2614
+ ownership mode.
2615
 
2616
+ *Effects:* Calls `m.try_lock_shared()`.
 
2617
 
2618
+ *Ensures:* `pm == addressof(m)` and `owns == res` where `res` is the
2619
+ value returned by the call to `m.try_lock_shared()`.
2620
 
2621
  ``` cpp
2622
  shared_lock(mutex_type& m, adopt_lock_t);
2623
  ```
2624
 
2625
+ *Preconditions:* The calling thread has shared ownership of the mutex.
2626
 
2627
+ *Ensures:* `pm == addressof(m)` and `owns == true`.
 
 
2628
 
2629
  ``` cpp
2630
  template<class Clock, class Duration>
2631
  shared_lock(mutex_type& m,
2632
  const chrono::time_point<Clock, Duration>& abs_time);
2633
  ```
2634
 
2635
+ *Preconditions:* The calling thread does not own the mutex for any
2636
+ ownership mode.
2637
 
2638
+ *Effects:* Calls `m.try_lock_shared_until(abs_time)`.
 
2639
 
2640
+ *Ensures:* `pm == addressof(m)` and `owns == res` where `res` is the
2641
+ value returned by the call to `m.try_lock_shared_until(abs_time)`.
2642
 
2643
  ``` cpp
2644
  template<class Rep, class Period>
2645
  shared_lock(mutex_type& m,
2646
  const chrono::duration<Rep, Period>& rel_time);
2647
  ```
2648
 
2649
+ *Preconditions:* The calling thread does not own the mutex for any
2650
+ ownership mode.
2651
 
2652
+ *Effects:* Calls `m.try_lock_shared_for(rel_time)`.
 
2653
 
2654
+ *Ensures:* `pm == addressof(m)` and `owns == res` where `res` is the
2655
+ value returned by the call to `m.try_lock_shared_for(rel_time)`.
2656
 
2657
  ``` cpp
2658
  ~shared_lock();
2659
  ```
2660
 
 
2662
 
2663
  ``` cpp
2664
  shared_lock(shared_lock&& sl) noexcept;
2665
  ```
2666
 
2667
+ *Ensures:* `pm == sl_p.pm` and `owns == sl_p.owns` (where `sl_p` is the
2668
+ state of `sl` just prior to this construction), `sl.pm == nullptr` and
2669
+ `sl.owns == false`.
2670
 
2671
  ``` cpp
2672
  shared_lock& operator=(shared_lock&& sl) noexcept;
2673
  ```
2674
 
2675
  *Effects:* If `owns` calls `pm->unlock_shared()`.
2676
 
2677
+ *Ensures:* `pm == sl_p.pm` and `owns == sl_p.owns` (where `sl_p` is the
2678
+ state of `sl` just prior to this assignment), `sl.pm == nullptr` and
2679
+ `sl.owns == false`.
2680
 
2681
+ ##### Locking <a id="thread.lock.shared.locking">[[thread.lock.shared.locking]]</a>
2682
 
2683
  ``` cpp
2684
  void lock();
2685
  ```
2686
 
2687
  *Effects:* As if by `pm->lock_shared()`.
2688
 
2689
+ *Ensures:* `owns == true`.
2690
 
2691
  *Throws:* Any exception thrown by `pm->lock_shared()`. `system_error`
2692
+ when an exception is required [[thread.req.exception]].
2693
 
2694
  *Error conditions:*
2695
 
2696
  - `operation_not_permitted` — if `pm` is `nullptr`.
2697
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
 
2702
 
2703
  *Effects:* As if by `pm->try_lock_shared()`.
2704
 
2705
  *Returns:* The value returned by the call to `pm->try_lock_shared()`.
2706
 
2707
+ *Ensures:* `owns == res`, where `res` is the value returned by the call
2708
+ to `pm->try_lock_shared()`.
2709
 
2710
  *Throws:* Any exception thrown by `pm->try_lock_shared()`.
2711
+ `system_error` when an exception is required [[thread.req.exception]].
 
2712
 
2713
  *Error conditions:*
2714
 
2715
  - `operation_not_permitted` — if `pm` is `nullptr`.
2716
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
2717
 
2718
  ``` cpp
2719
  template<class Clock, class Duration>
2720
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
 
2721
  ```
2722
 
2723
  *Effects:* As if by `pm->try_lock_shared_until(abs_time)`.
2724
 
2725
  *Returns:* The value returned by the call to
2726
  `pm->try_lock_shared_until(abs_time)`.
2727
 
2728
+ *Ensures:* `owns == res`, where `res` is the value returned by the call
2729
+ to `pm->try_lock_shared_until(abs_time)`.
2730
 
2731
  *Throws:* Any exception thrown by `pm->try_lock_shared_until(abs_time)`.
2732
+ `system_error` when an exception is required [[thread.req.exception]].
 
2733
 
2734
  *Error conditions:*
2735
 
2736
  - `operation_not_permitted` — if `pm` is `nullptr`.
2737
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
 
2744
  *Effects:* As if by `pm->try_lock_shared_for(rel_time)`.
2745
 
2746
  *Returns:* The value returned by the call to
2747
  `pm->try_lock_shared_for(rel_time)`.
2748
 
2749
+ *Ensures:* `owns == res`, where `res` is the value returned by the call
2750
+ to `pm->try_lock_shared_for(rel_time)`.
2751
 
2752
  *Throws:* Any exception thrown by `pm->try_lock_shared_for(rel_time)`.
2753
+ `system_error` when an exception is required [[thread.req.exception]].
 
2754
 
2755
  *Error conditions:*
2756
 
2757
  - `operation_not_permitted` — if `pm` is `nullptr`.
2758
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
 
2761
  void unlock();
2762
  ```
2763
 
2764
  *Effects:* As if by `pm->unlock_shared()`.
2765
 
2766
+ *Ensures:* `owns == false`.
2767
 
2768
  *Throws:* `system_error` when an exception is
2769
+ required [[thread.req.exception]].
2770
 
2771
  *Error conditions:*
2772
 
2773
  - `operation_not_permitted` — if on entry `owns` is `false`.
2774
 
2775
+ ##### Modifiers <a id="thread.lock.shared.mod">[[thread.lock.shared.mod]]</a>
2776
 
2777
  ``` cpp
2778
  void swap(shared_lock& sl) noexcept;
2779
  ```
2780
 
 
2784
  mutex_type* release() noexcept;
2785
  ```
2786
 
2787
  *Returns:* The previous value of `pm`.
2788
 
2789
+ *Ensures:* `pm == nullptr` and `owns == false`.
2790
 
2791
  ``` cpp
2792
  template<class Mutex>
2793
  void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
2794
  ```
2795
 
2796
  *Effects:* As if by `x.swap(y)`.
2797
 
2798
+ ##### Observers <a id="thread.lock.shared.obs">[[thread.lock.shared.obs]]</a>
2799
 
2800
  ``` cpp
2801
  bool owns_lock() const noexcept;
2802
  ```
2803
 
 
2819
 
2820
  ``` cpp
2821
  template<class L1, class L2, class... L3> int try_lock(L1&, L2&, L3&...);
2822
  ```
2823
 
2824
+ *Preconditions:* Each template parameter type meets the *Cpp17Lockable*
2825
  requirements.
2826
 
2827
  [*Note 1*: The `unique_lock` class template meets these requirements
2828
  when suitably instantiated. — *end note*]
2829
 
2830
  *Effects:* Calls `try_lock()` for each argument in order beginning with
2831
  the first until all arguments have been processed or a call to
2832
  `try_lock()` fails, either by returning `false` or by throwing an
2833
+ exception. If a call to `try_lock()` fails, `unlock()` is called for all
2834
+ prior arguments with no further calls to `try_lock()`.
 
2835
 
2836
  *Returns:* `-1` if all calls to `try_lock()` returned `true`, otherwise
2837
  a zero-based index value that indicates the argument for which
2838
  `try_lock()` returned `false`.
2839
 
2840
  ``` cpp
2841
  template<class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);
2842
  ```
2843
 
2844
+ *Preconditions:* Each template parameter type meets the *Cpp17Lockable*
2845
+ requirements.
2846
 
2847
  [*Note 2*: The `unique_lock` class template meets these requirements
2848
  when suitably instantiated. — *end note*]
2849
 
2850
  *Effects:* All arguments are locked via a sequence of calls to `lock()`,
2851
+ `try_lock()`, or `unlock()` on each argument. The sequence of calls does
2852
+ not result in deadlock, but is otherwise unspecified.
2853
 
2854
  [*Note 3*: A deadlock avoidance algorithm such as try-and-back-off must
2855
  be used, but the specific algorithm is not specified to avoid
2856
  over-constraining implementations. — *end note*]
2857
 
2858
+ If a call to `lock()` or `try_lock()` throws an exception, `unlock()` is
2859
+ called for any argument that had been locked by a call to `lock()` or
2860
+ `try_lock()`.
2861
 
2862
  ### Call once <a id="thread.once">[[thread.once]]</a>
2863
 
2864
  #### Struct `once_flag` <a id="thread.once.onceflag">[[thread.once.onceflag]]</a>
2865
 
 
2879
 
2880
  ``` cpp
2881
  constexpr once_flag() noexcept;
2882
  ```
2883
 
 
 
2884
  *Synchronization:* The construction of a `once_flag` object is not
2885
  synchronized.
2886
 
2887
+ *Ensures:* The object’s internal state is set to indicate to an
2888
  invocation of `call_once` with the object as its initial argument that
2889
  no function has been called.
2890
 
2891
  #### Function `call_once` <a id="thread.once.callonce">[[thread.once.callonce]]</a>
2892
 
2893
  ``` cpp
2894
  template<class Callable, class... Args>
2895
  void call_once(once_flag& flag, Callable&& func, Args&&... args);
2896
  ```
2897
 
2898
+ *Mandates:* `is_invocable_v<Callable, Args...>` is `true`.
 
 
 
 
 
 
2899
 
2900
  *Effects:* An execution of `call_once` that does not call its `func` is
2901
  a *passive* execution. An execution of `call_once` that calls its `func`
2902
+ is an *active* execution. An active execution calls *INVOKE*(
2903
  std::forward\<Callable\>(func), std::forward\<Args\>(args)...). If such
2904
  a call to `func` throws an exception the execution is *exceptional*,
2905
+ otherwise it is *returning*. An exceptional execution propagates the
2906
+ exception to the caller of `call_once`. Among all executions of
2907
+ `call_once` for any given `once_flag`: at most one is a returning
2908
+ execution; if there is a returning execution, it is the last active
2909
+ execution; and there are passive executions only if there is a returning
2910
+ execution.
2911
 
2912
  [*Note 1*: Passive executions allow other threads to reliably observe
2913
  the results produced by the earlier returning execution. — *end note*]
2914
 
2915
  *Synchronization:* For any given `once_flag`: all active executions
2916
  occur in a total order; completion of an active execution synchronizes
2917
+ with [[intro.multithread]] the start of the next one in this total
2918
  order; and the returning execution synchronizes with the return from all
2919
  passive executions.
2920
 
2921
  *Throws:* `system_error` when an exception is
2922
+ required [[thread.req.exception]], or any exception thrown by `func`.
2923
 
2924
  [*Example 1*:
2925
 
2926
  ``` cpp
2927
  // global flag, regular function
 
2957
 
2958
  Condition variables provide synchronization primitives used to block a
2959
  thread until notified by some other thread that some condition is met or
2960
  until a system time is reached. Class `condition_variable` provides a
2961
  condition variable that can only wait on an object of type
2962
+ `unique_lock<mutex>`, allowing the implementation to be more efficient.
2963
  Class `condition_variable_any` provides a general condition variable
2964
  that can wait on objects of user-supplied lock types.
2965
 
2966
  Condition variables permit concurrent invocation of the `wait`,
2967
  `wait_for`, `wait_until`, `notify_one` and `notify_all` member
2968
  functions.
2969
 
2970
+ The executions of `notify_one` and `notify_all` are atomic. The
2971
+ executions of `wait`, `wait_for`, and `wait_until` are performed in
2972
  three atomic parts:
2973
 
2974
  1. the release of the mutex and entry into the waiting state;
2975
  2. the unblocking of the wait; and
2976
  3. the reacquisition of the lock.
2977
 
2978
+ The implementation behaves as if all executions of `notify_one`,
2979
  `notify_all`, and each part of the `wait`, `wait_for`, and `wait_until`
2980
  executions are executed in a single unspecified total order consistent
2981
  with the "happens before" order.
2982
 
2983
  Condition variable construction and destruction need not be
2984
  synchronized.
2985
 
2986
+ ### Header `<condition_variable>` synopsis <a id="condition.variable.syn">[[condition.variable.syn]]</a>
2987
 
2988
  ``` cpp
2989
  namespace std {
2990
  class condition_variable;
2991
  class condition_variable_any;
 
3000
 
3001
  ``` cpp
3002
  void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
3003
  ```
3004
 
3005
+ *Preconditions:* `lk` is locked by the calling thread and either
3006
 
3007
  - no other thread is waiting on `cond`, or
3008
  - `lk.mutex()` returns the same value for each of the lock arguments
3009
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
3010
  `wait_until`) threads.
3011
 
3012
  *Effects:* Transfers ownership of the lock associated with `lk` into
3013
  internal storage and schedules `cond` to be notified when the current
3014
  thread exits, after all objects of thread storage duration associated
3015
+ with the current thread have been destroyed. This notification is
3016
+ equivalent to:
3017
 
3018
  ``` cpp
3019
  lk.unlock();
3020
  cond.notify_all();
3021
  ```
 
3023
  *Synchronization:* The implied `lk.unlock()` call is sequenced after the
3024
  destruction of all objects with thread storage duration associated with
3025
  the current thread.
3026
 
3027
  [*Note 1*: The supplied lock will be held until the thread exits, and
3028
+ care should be taken to ensure that this does not cause deadlock due to
3029
  lock ordering issues. After calling `notify_all_at_thread_exit` it is
3030
  recommended that the thread should be exited as soon as possible, and
3031
  that no blocking or time-consuming tasks are run on that
3032
  thread. — *end note*]
3033
 
 
3042
 
3043
  ``` cpp
3044
  namespace std {
3045
  class condition_variable {
3046
  public:
 
3047
  condition_variable();
3048
  ~condition_variable();
3049
 
3050
  condition_variable(const condition_variable&) = delete;
3051
  condition_variable& operator=(const condition_variable&) = delete;
 
3060
  const chrono::time_point<Clock, Duration>& abs_time);
3061
  template<class Clock, class Duration, class Predicate>
3062
  bool wait_until(unique_lock<mutex>& lock,
3063
  const chrono::time_point<Clock, Duration>& abs_time,
3064
  Predicate pred);
 
3065
  template<class Rep, class Period>
3066
  cv_status wait_for(unique_lock<mutex>& lock,
3067
  const chrono::duration<Rep, Period>& rel_time);
3068
  template<class Rep, class Period, class Predicate>
3069
  bool wait_for(unique_lock<mutex>& lock,
3070
  const chrono::duration<Rep, Period>& rel_time,
3071
  Predicate pred);
3072
 
3073
+ using native_handle_type = implementation-defined; // see~[thread.req.native]
3074
+ native_handle_type native_handle(); // see~[thread.req.native]
3075
  };
3076
  }
3077
  ```
3078
 
3079
+ The class `condition_variable` is a standard-layout class
3080
+ [[class.prop]].
3081
 
3082
  ``` cpp
3083
  condition_variable();
3084
  ```
3085
 
 
 
3086
  *Throws:* `system_error` when an exception is
3087
+ required [[thread.req.exception]].
3088
 
3089
  *Error conditions:*
3090
 
3091
  - `resource_unavailable_try_again` — if some non-memory resource
3092
  limitation prevents initialization.
3093
 
3094
  ``` cpp
3095
  ~condition_variable();
3096
  ```
3097
 
3098
+ *Preconditions:* There is no thread blocked on `*this`.
3099
 
3100
+ [*Note 1*: That is, all threads have been notified; they could
3101
  subsequently block on the lock specified in the wait. This relaxes the
3102
  usual rules, which would have required all wait calls to happen before
3103
+ destruction. Only the notification to unblock the wait needs to happen
3104
+ before destruction. The user should take care to ensure that no threads
3105
  wait on `*this` once the destructor has been started, especially when
3106
  the waiting threads are calling the wait functions in a loop or using
3107
  the overloads of `wait`, `wait_for`, or `wait_until` that take a
3108
  predicate. — *end note*]
3109
 
 
 
3110
  ``` cpp
3111
  void notify_one() noexcept;
3112
  ```
3113
 
3114
  *Effects:* If any threads are blocked waiting for `*this`, unblocks one
 
3122
 
3123
  ``` cpp
3124
  void wait(unique_lock<mutex>& lock);
3125
  ```
3126
 
3127
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
3128
+ locked by the calling thread, and either
3129
 
3130
  - no other thread is waiting on this `condition_variable` object or
3131
  - `lock.mutex()` returns the same value for each of the `lock` arguments
3132
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
3133
  `wait_until`) threads.
 
3139
  then returns.
3140
  - The function will unblock when signaled by a call to `notify_one()` or
3141
  a call to `notify_all()`, or spuriously.
3142
 
3143
  *Remarks:* If the function fails to meet the postcondition,
3144
+ `terminate()` is called [[except.terminate]].
3145
 
3146
  [*Note 2*: This can happen if the re-locking of the mutex throws an
3147
  exception. — *end note*]
3148
 
3149
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
3150
+ the calling thread.
3151
 
3152
  *Throws:* Nothing.
3153
 
3154
  ``` cpp
3155
  template<class Predicate>
3156
  void wait(unique_lock<mutex>& lock, Predicate pred);
3157
  ```
3158
 
3159
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
3160
+ locked by the calling thread, and either
3161
 
3162
  - no other thread is waiting on this `condition_variable` object or
3163
  - `lock.mutex()` returns the same value for each of the `lock` arguments
3164
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
3165
  `wait_until`) threads.
 
3170
  while (!pred())
3171
  wait(lock);
3172
  ```
3173
 
3174
  *Remarks:* If the function fails to meet the postcondition,
3175
+ `terminate()` is called [[except.terminate]].
3176
 
3177
  [*Note 3*: This can happen if the re-locking of the mutex throws an
3178
  exception. — *end note*]
3179
 
3180
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
3181
+ the calling thread.
3182
 
3183
  *Throws:* Any exception thrown by `pred`.
3184
 
3185
  ``` cpp
3186
  template<class Clock, class Duration>
3187
  cv_status wait_until(unique_lock<mutex>& lock,
3188
  const chrono::time_point<Clock, Duration>& abs_time);
3189
  ```
3190
 
3191
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
3192
+ locked by the calling thread, and either
3193
 
3194
  - no other thread is waiting on this `condition_variable` object or
3195
  - `lock.mutex()` returns the same value for each of the `lock` arguments
3196
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
3197
  `wait_until`) threads.
 
3201
  - Atomically calls `lock.unlock()` and blocks on `*this`.
3202
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock),
3203
  then returns.
3204
  - The function will unblock when signaled by a call to `notify_one()`, a
3205
  call to `notify_all()`, expiration of the absolute
3206
+ timeout [[thread.req.timing]] specified by `abs_time`, or spuriously.
3207
+ - If the function exits via an exception, `lock.lock()` is called prior
3208
+ to exiting the function.
 
3209
 
3210
  *Remarks:* If the function fails to meet the postcondition,
3211
+ `terminate()` is called [[except.terminate]].
3212
 
3213
  [*Note 4*: This can happen if the re-locking of the mutex throws an
3214
  exception. — *end note*]
3215
 
3216
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
3217
+ the calling thread.
3218
 
3219
  *Returns:* `cv_status::timeout` if the absolute
3220
+ timeout [[thread.req.timing]] specified by `abs_time` expired, otherwise
3221
+ `cv_status::no_timeout`.
3222
 
3223
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
3224
 
3225
  ``` cpp
3226
  template<class Rep, class Period>
3227
  cv_status wait_for(unique_lock<mutex>& lock,
3228
  const chrono::duration<Rep, Period>& rel_time);
3229
  ```
3230
 
3231
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
3232
+ locked by the calling thread, and either
3233
 
3234
  - no other thread is waiting on this `condition_variable` object or
3235
  - `lock.mutex()` returns the same value for each of the `lock` arguments
3236
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
3237
  `wait_until`) threads.
 
3241
  ``` cpp
3242
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
3243
  ```
3244
 
3245
  *Returns:* `cv_status::timeout` if the relative
3246
+ timeout [[thread.req.timing]] specified by `rel_time` expired, otherwise
3247
+ `cv_status::no_timeout`.
3248
 
3249
  *Remarks:* If the function fails to meet the postcondition,
3250
+ `terminate()` is called [[except.terminate]].
3251
 
3252
  [*Note 5*: This can happen if the re-locking of the mutex throws an
3253
  exception. — *end note*]
3254
 
3255
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
3256
+ the calling thread.
3257
 
3258
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
3259
 
3260
  ``` cpp
3261
  template<class Clock, class Duration, class Predicate>
3262
  bool wait_until(unique_lock<mutex>& lock,
3263
  const chrono::time_point<Clock, Duration>& abs_time,
3264
  Predicate pred);
3265
  ```
3266
 
3267
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
3268
+ locked by the calling thread, and either
3269
 
3270
  - no other thread is waiting on this `condition_variable` object or
3271
  - `lock.mutex()` returns the same value for each of the `lock` arguments
3272
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
3273
  `wait_until`) threads.
 
3280
  return pred();
3281
  return true;
3282
  ```
3283
 
3284
  *Remarks:* If the function fails to meet the postcondition,
3285
+ `terminate()` is called [[except.terminate]].
3286
 
3287
  [*Note 6*: This can happen if the re-locking of the mutex throws an
3288
  exception. — *end note*]
3289
 
3290
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
3291
+ the calling thread.
3292
 
3293
  [*Note 7*: The returned value indicates whether the predicate evaluated
3294
  to `true` regardless of whether the timeout was
3295
  triggered. — *end note*]
3296
 
3297
+ *Throws:* Timeout-related exceptions [[thread.req.timing]] or any
3298
  exception thrown by `pred`.
3299
 
3300
  ``` cpp
3301
  template<class Rep, class Period, class Predicate>
3302
  bool wait_for(unique_lock<mutex>& lock,
3303
  const chrono::duration<Rep, Period>& rel_time,
3304
  Predicate pred);
3305
  ```
3306
 
3307
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
3308
+ locked by the calling thread, and either
3309
 
3310
  - no other thread is waiting on this `condition_variable` object or
3311
  - `lock.mutex()` returns the same value for each of the `lock` arguments
3312
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
3313
  `wait_until`) threads.
 
3320
 
3321
  [*Note 8*: There is no blocking if `pred()` is initially `true`, even
3322
  if the timeout has already expired. — *end note*]
3323
 
3324
  *Remarks:* If the function fails to meet the postcondition,
3325
+ `terminate()` is called [[except.terminate]].
3326
 
3327
  [*Note 9*: This can happen if the re-locking of the mutex throws an
3328
  exception. — *end note*]
3329
 
3330
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
3331
+ the calling thread.
3332
 
3333
  [*Note 10*: The returned value indicates whether the predicate
3334
  evaluates to `true` regardless of whether the timeout was
3335
  triggered. — *end note*]
3336
 
3337
+ *Throws:* Timeout-related exceptions [[thread.req.timing]] or any
3338
  exception thrown by `pred`.
3339
 
3340
  ### Class `condition_variable_any` <a id="thread.condition.condvarany">[[thread.condition.condvarany]]</a>
3341
 
3342
+ A `Lock` type shall meet the *Cpp17BasicLockable* requirements
3343
+ [[thread.req.lockable.basic]].
3344
 
3345
  [*Note 1*: All of the standard mutex types meet this requirement. If a
3346
  `Lock` type other than one of the standard mutex types or a
3347
  `unique_lock` wrapper for a standard mutex type is used with
3348
+ `condition_variable_any`, the user should ensure that any necessary
3349
  synchronization is in place with respect to the predicate associated
3350
  with the `condition_variable_any` instance. — *end note*]
3351
 
3352
  ``` cpp
3353
  namespace std {
 
3359
  condition_variable_any(const condition_variable_any&) = delete;
3360
  condition_variable_any& operator=(const condition_variable_any&) = delete;
3361
 
3362
  void notify_one() noexcept;
3363
  void notify_all() noexcept;
3364
+
3365
+ // [thread.condvarany.wait], noninterruptible waits
3366
  template<class Lock>
3367
  void wait(Lock& lock);
3368
  template<class Lock, class Predicate>
3369
  void wait(Lock& lock, Predicate pred);
3370
 
 
3374
  bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time,
3375
  Predicate pred);
3376
  template<class Lock, class Rep, class Period>
3377
  cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
3378
  template<class Lock, class Rep, class Period, class Predicate>
3379
+ bool wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred);
3380
+
3381
+ // [thread.condvarany.intwait], interruptible waits
3382
+ template<class Lock, class Predicate>
3383
+ bool wait(Lock& lock, stop_token stoken, Predicate pred);
3384
+ template<class Lock, class Clock, class Duration, class Predicate>
3385
+ bool wait_until(Lock& lock, stop_token stoken,
3386
+ const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
3387
+ template<class Lock, class Rep, class Period, class Predicate>
3388
+ bool wait_for(Lock& lock, stop_token stoken,
3389
+ const chrono::duration<Rep, Period>& rel_time, Predicate pred);
3390
  };
3391
  }
3392
  ```
3393
 
3394
  ``` cpp
3395
  condition_variable_any();
3396
  ```
3397
 
 
 
3398
  *Throws:* `bad_alloc` or `system_error` when an exception is
3399
+ required [[thread.req.exception]].
3400
 
3401
  *Error conditions:*
3402
 
3403
  - `resource_unavailable_try_again` — if some non-memory resource
3404
  limitation prevents initialization.
 
3407
 
3408
  ``` cpp
3409
  ~condition_variable_any();
3410
  ```
3411
 
3412
+ *Preconditions:* There is no thread blocked on `*this`.
3413
 
3414
+ [*Note 1*: That is, all threads have been notified; they could
3415
  subsequently block on the lock specified in the wait. This relaxes the
3416
  usual rules, which would have required all wait calls to happen before
3417
+ destruction. Only the notification to unblock the wait needs to happen
3418
+ before destruction. The user should take care to ensure that no threads
3419
  wait on `*this` once the destructor has been started, especially when
3420
  the waiting threads are calling the wait functions in a loop or using
3421
  the overloads of `wait`, `wait_for`, or `wait_until` that take a
3422
  predicate. — *end note*]
3423
 
 
 
3424
  ``` cpp
3425
  void notify_one() noexcept;
3426
  ```
3427
 
3428
  *Effects:* If any threads are blocked waiting for `*this`, unblocks one
 
3432
  void notify_all() noexcept;
3433
  ```
3434
 
3435
  *Effects:* Unblocks all threads that are blocked waiting for `*this`.
3436
 
3437
+ #### Noninterruptible waits <a id="thread.condvarany.wait">[[thread.condvarany.wait]]</a>
3438
+
3439
  ``` cpp
3440
  template<class Lock>
3441
  void wait(Lock& lock);
3442
  ```
3443
 
 
 
 
 
3444
  *Effects:*
3445
 
3446
  - Atomically calls `lock.unlock()` and blocks on `*this`.
3447
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock)
3448
  and returns.
3449
  - The function will unblock when signaled by a call to `notify_one()`, a
3450
  call to `notify_all()`, or spuriously.
3451
 
3452
  *Remarks:* If the function fails to meet the postcondition,
3453
+ `terminate()` is called [[except.terminate]].
3454
 
3455
+ [*Note 1*: This can happen if the re-locking of the mutex throws an
3456
  exception. — *end note*]
3457
 
3458
+ *Ensures:* `lock` is locked by the calling thread.
3459
 
3460
  *Throws:* Nothing.
3461
 
3462
  ``` cpp
3463
  template<class Lock, class Predicate>
 
3481
  - Atomically calls `lock.unlock()` and blocks on `*this`.
3482
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock)
3483
  and returns.
3484
  - The function will unblock when signaled by a call to `notify_one()`, a
3485
  call to `notify_all()`, expiration of the absolute
3486
+ timeout [[thread.req.timing]] specified by `abs_time`, or spuriously.
3487
+ - If the function exits via an exception, `lock.lock()` is called prior
3488
+ to exiting the function.
 
3489
 
3490
  *Remarks:* If the function fails to meet the postcondition,
3491
+ `terminate()` is called [[except.terminate]].
3492
 
3493
+ [*Note 2*: This can happen if the re-locking of the mutex throws an
3494
  exception. — *end note*]
3495
 
3496
+ *Ensures:* `lock` is locked by the calling thread.
3497
 
3498
  *Returns:* `cv_status::timeout` if the absolute
3499
+ timeout [[thread.req.timing]] specified by `abs_time` expired, otherwise
3500
+ `cv_status::no_timeout`.
3501
 
3502
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
3503
 
3504
  ``` cpp
3505
  template<class Lock, class Rep, class Period>
3506
  cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
3507
  ```
 
3511
  ``` cpp
3512
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
3513
  ```
3514
 
3515
  *Returns:* `cv_status::timeout` if the relative
3516
+ timeout [[thread.req.timing]] specified by `rel_time` expired, otherwise
3517
+ `cv_status::no_timeout`.
3518
 
3519
  *Remarks:* If the function fails to meet the postcondition,
3520
+ `terminate()` is called [[except.terminate]].
3521
 
3522
+ [*Note 3*: This can happen if the re-locking of the mutex throws an
3523
  exception. — *end note*]
3524
 
3525
+ *Ensures:* `lock` is locked by the calling thread.
3526
 
3527
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
3528
 
3529
  ``` cpp
3530
  template<class Lock, class Clock, class Duration, class Predicate>
3531
  bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
3532
  ```
 
3538
  if (wait_until(lock, abs_time) == cv_status::timeout)
3539
  return pred();
3540
  return true;
3541
  ```
3542
 
3543
+ [*Note 4*: There is no blocking if `pred()` is initially `true`, or if
3544
  the timeout has already expired. — *end note*]
3545
 
3546
+ [*Note 5*: The returned value indicates whether the predicate evaluates
3547
  to `true` regardless of whether the timeout was
3548
  triggered. — *end note*]
3549
 
3550
  ``` cpp
3551
  template<class Lock, class Rep, class Period, class Predicate>
 
3556
 
3557
  ``` cpp
3558
  return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));
3559
  ```
3560
 
3561
+ #### Interruptible waits <a id="thread.condvarany.intwait">[[thread.condvarany.intwait]]</a>
3562
+
3563
+ The following wait functions will be notified when there is a stop
3564
+ request on the passed `stop_token`. In that case the functions return
3565
+ immediately, returning `false` if the predicate evaluates to `false`.
3566
+
3567
+ ``` cpp
3568
+ template<class Lock, class Predicate>
3569
+ bool wait(Lock& lock, stop_token stoken, Predicate pred);
3570
+ ```
3571
+
3572
+ *Effects:* Registers for the duration of this call `*this` to get
3573
+ notified on a stop request on `stoken` during this call and then
3574
+ equivalent to:
3575
+
3576
+ ``` cpp
3577
+ while (!stoken.stop_requested()) {
3578
+ if (pred())
3579
+ return true;
3580
+ wait(lock);
3581
+ }
3582
+ return pred();
3583
+ ```
3584
+
3585
+ [*Note 1*: The returned value indicates whether the predicate evaluated
3586
+ to `true` regardless of whether there was a stop request. — *end note*]
3587
+
3588
+ *Ensures:* `lock` is locked by the calling thread.
3589
+
3590
+ *Remarks:* If the function fails to meet the postcondition, `terminate`
3591
+ is called [[except.terminate]].
3592
+
3593
+ [*Note 2*: This can happen if the re-locking of the mutex throws an
3594
+ exception. — *end note*]
3595
+
3596
+ *Throws:* Any exception thrown by `pred`.
3597
+
3598
+ ``` cpp
3599
+ template<class Lock, class Clock, class Duration, class Predicate>
3600
+ bool wait_until(Lock& lock, stop_token stoken,
3601
+ const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
3602
+ ```
3603
+
3604
+ *Effects:* Registers for the duration of this call `*this` to get
3605
+ notified on a stop request on `stoken` during this call and then
3606
+ equivalent to:
3607
+
3608
+ ``` cpp
3609
+ while (!stoken.stop_requested()) {
3610
+ if (pred())
3611
+ return true;
3612
+ if (cv.wait_until(lock, abs_time) == cv_status::timeout)
3613
+ return pred();
3614
+ }
3615
+ return pred();
3616
+ ```
3617
+
3618
+ [*Note 3*: There is no blocking if `pred()` is initially `true`,
3619
+ `stoken.stop_requested()` was already `true` or the timeout has already
3620
+ expired. — *end note*]
3621
+
3622
+ [*Note 4*: The returned value indicates whether the predicate evaluated
3623
+ to `true` regardless of whether the timeout was triggered or a stop
3624
+ request was made. — *end note*]
3625
+
3626
+ *Ensures:* `lock` is locked by the calling thread.
3627
+
3628
+ *Remarks:* If the function fails to meet the postcondition, `terminate`
3629
+ is called [[except.terminate]].
3630
+
3631
+ [*Note 5*: This can happen if the re-locking of the mutex throws an
3632
+ exception. — *end note*]
3633
+
3634
+ *Throws:* Timeout-related exceptions [[thread.req.timing]], or any
3635
+ exception thrown by `pred`.
3636
+
3637
+ ``` cpp
3638
+ template<class Lock, class Rep, class Period, class Predicate>
3639
+ bool wait_for(Lock& lock, stop_token stoken,
3640
+ const chrono::duration<Rep, Period>& rel_time, Predicate pred);
3641
+ ```
3642
+
3643
+ *Effects:* Equivalent to:
3644
+
3645
+ ``` cpp
3646
+ return wait_until(lock, std::move(stoken), chrono::steady_clock::now() + rel_time,
3647
+ std::move(pred));
3648
+ ```
3649
+
3650
+ ## Semaphore <a id="thread.sema">[[thread.sema]]</a>
3651
+
3652
+ Semaphores are lightweight synchronization primitives used to constrain
3653
+ concurrent access to a shared resource. They are widely used to
3654
+ implement other synchronization primitives and, whenever both are
3655
+ applicable, can be more efficient than condition variables.
3656
+
3657
+ A counting semaphore is a semaphore object that models a non-negative
3658
+ resource count. A binary semaphore is a semaphore object that has only
3659
+ two states. A binary semaphore should be more efficient than the default
3660
+ implementation of a counting semaphore with a unit resource count.
3661
+
3662
+ ### Header `<semaphore>` synopsis <a id="semaphore.syn">[[semaphore.syn]]</a>
3663
+
3664
+ ``` cpp
3665
+ namespace std {
3666
+ template<ptrdiff_t least_max_value = implementation-defined>
3667
+ class counting_semaphore;
3668
+
3669
+ using binary_semaphore = counting_semaphore<1>;
3670
+ }
3671
+ ```
3672
+
3673
+ ### Class template `counting_semaphore` <a id="thread.sema.cnt">[[thread.sema.cnt]]</a>
3674
+
3675
+ ``` cpp
3676
+ namespace std {
3677
+ template<ptrdiff_t least_max_value = implementation-defined>
3678
+ class counting_semaphore {
3679
+ public:
3680
+ static constexpr ptrdiff_t max() noexcept;
3681
+
3682
+ constexpr explicit counting_semaphore(ptrdiff_t desired);
3683
+ ~counting_semaphore();
3684
+
3685
+ counting_semaphore(const counting_semaphore&) = delete;
3686
+ counting_semaphore& operator=(const counting_semaphore&) = delete;
3687
+
3688
+ void release(ptrdiff_t update = 1);
3689
+ void acquire();
3690
+ bool try_acquire() noexcept;
3691
+ template<class Rep, class Period>
3692
+ bool try_acquire_for(const chrono::duration<Rep, Period>& rel_time);
3693
+ template<class Clock, class Duration>
3694
+ bool try_acquire_until(const chrono::time_point<Clock, Duration>& abs_time);
3695
+
3696
+ private:
3697
+ ptrdiff_t counter; // exposition only
3698
+ };
3699
+ }
3700
+ ```
3701
+
3702
+ Class template `counting_semaphore` maintains an internal counter that
3703
+ is initialized when the semaphore is created. The counter is decremented
3704
+ when a thread acquires the semaphore, and is incremented when a thread
3705
+ releases the semaphore. If a thread tries to acquire the semaphore when
3706
+ the counter is zero, the thread will block until another thread
3707
+ increments the counter by releasing the semaphore.
3708
+
3709
+ `least_max_value` shall be non-negative; otherwise the program is
3710
+ ill-formed.
3711
+
3712
+ Concurrent invocations of the member functions of `counting_semaphore`,
3713
+ other than its destructor, do not introduce data races.
3714
+
3715
+ ``` cpp
3716
+ static constexpr ptrdiff_t max() noexcept;
3717
+ ```
3718
+
3719
+ *Returns:* The maximum value of `counter`. This value is greater than or
3720
+ equal to `least_max_value`.
3721
+
3722
+ ``` cpp
3723
+ constexpr explicit counting_semaphore(ptrdiff_t desired);
3724
+ ```
3725
+
3726
+ *Preconditions:* `desired >= 0` is `true`, and `desired <= max()` is
3727
+ `true`.
3728
+
3729
+ *Effects:* Initializes `counter` with `desired`.
3730
+
3731
+ *Throws:* Nothing.
3732
+
3733
+ ``` cpp
3734
+ void release(ptrdiff_t update = 1);
3735
+ ```
3736
+
3737
+ *Preconditions:* `update >= 0` is `true`, and
3738
+ `update <= max() - counter` is `true`.
3739
+
3740
+ *Effects:* Atomically execute `counter += update`. Then, unblocks any
3741
+ threads that are waiting for `counter` to be greater than zero.
3742
+
3743
+ *Synchronization:* Strongly happens before invocations of `try_acquire`
3744
+ that observe the result of the effects.
3745
+
3746
+ *Throws:* `system_error` when an exception is
3747
+ required [[thread.req.exception]].
3748
+
3749
+ *Error conditions:* Any of the error conditions allowed for mutex
3750
+ types [[thread.mutex.requirements.mutex]].
3751
+
3752
+ ``` cpp
3753
+ bool try_acquire() noexcept;
3754
+ ```
3755
+
3756
+ *Effects:* Attempts to atomically decrement `counter` if it is positive,
3757
+ without blocking. If `counter` is not decremented, there is no effect
3758
+ and `try_acquire` immediately returns. An implementation may fail to
3759
+ decrement `counter` even if it is positive.
3760
+
3761
+ [*Note 1*: This spurious failure is normally uncommon, but allows
3762
+ interesting implementations based on a simple compare and
3763
+ exchange [[atomics]]. — *end note*]
3764
+
3765
+ An implementation should ensure that `try_acquire` does not consistently
3766
+ return `false` in the absence of contending semaphore operations.
3767
+
3768
+ *Returns:* `true` if `counter` was decremented, otherwise `false`.
3769
+
3770
+ ``` cpp
3771
+ void acquire();
3772
+ ```
3773
+
3774
+ *Effects:* Repeatedly performs the following steps, in order:
3775
+
3776
+ - Evaluates `try_acquire`. If the result is `true`, returns.
3777
+ - Blocks on `*this` until `counter` is greater than zero.
3778
+
3779
+ *Throws:* `system_error` when an exception is
3780
+ required [[thread.req.exception]].
3781
+
3782
+ *Error conditions:* Any of the error conditions allowed for mutex
3783
+ types [[thread.mutex.requirements.mutex]].
3784
+
3785
+ ``` cpp
3786
+ template<class Rep, class Period>
3787
+ bool try_acquire_for(const chrono::duration<Rep, Period>& rel_time);
3788
+ template<class Clock, class Duration>
3789
+ bool try_acquire_until(const chrono::time_point<Clock, Duration>& abs_time);
3790
+ ```
3791
+
3792
+ *Effects:* Repeatedly performs the following steps, in order:
3793
+
3794
+ - Evaluates `try_acquire()`. If the result is `true`, returns `true`.
3795
+ - Blocks on `*this` until `counter` is greater than zero or until the
3796
+ timeout expires. If it is unblocked by the timeout expiring, returns
3797
+ `false`.
3798
+
3799
+ The timeout expires [[thread.req.timing]] when the current time is after
3800
+ `abs_time` (for `try_acquire_until`) or when at least `rel_time` has
3801
+ passed from the start of the function (for `try_acquire_for`).
3802
+
3803
+ *Throws:* Timeout-related exceptions [[thread.req.timing]], or
3804
+ `system_error` when a non-timeout-related exception is
3805
+ required [[thread.req.exception]].
3806
+
3807
+ *Error conditions:* Any of the error conditions allowed for mutex
3808
+ types [[thread.mutex.requirements.mutex]].
3809
+
3810
+ ## Coordination types <a id="thread.coord">[[thread.coord]]</a>
3811
+
3812
+ This subclause describes various concepts related to thread
3813
+ coordination, and defines the coordination types `latch` and `barrier`.
3814
+ These types facilitate concurrent computation performed by a number of
3815
+ threads.
3816
+
3817
+ ### Latches <a id="thread.latch">[[thread.latch]]</a>
3818
+
3819
+ A latch is a thread coordination mechanism that allows any number of
3820
+ threads to block until an expected number of threads arrive at the latch
3821
+ (via the `count_down` function). The expected count is set when the
3822
+ latch is created. An individual latch is a single-use object; once the
3823
+ expected count has been reached, the latch cannot be reused.
3824
+
3825
+ #### Header `<latch>` synopsis <a id="latch.syn">[[latch.syn]]</a>
3826
+
3827
+ ``` cpp
3828
+ namespace std {
3829
+ class latch;
3830
+ }
3831
+ ```
3832
+
3833
+ #### Class `latch` <a id="thread.latch.class">[[thread.latch.class]]</a>
3834
+
3835
+ ``` cpp
3836
+ namespace std {
3837
+ class latch {
3838
+ public:
3839
+ static constexpr ptrdiff_t max() noexcept;
3840
+
3841
+ constexpr explicit latch(ptrdiff_t expected);
3842
+ ~latch();
3843
+
3844
+ latch(const latch&) = delete;
3845
+ latch& operator=(const latch&) = delete;
3846
+
3847
+ void count_down(ptrdiff_t update = 1);
3848
+ bool try_wait() const noexcept;
3849
+ void wait() const;
3850
+ void arrive_and_wait(ptrdiff_t update = 1);
3851
+
3852
+ private:
3853
+ ptrdiff_t counter; // exposition only
3854
+ };
3855
+ }
3856
+ ```
3857
+
3858
+ A `latch` maintains an internal counter that is initialized when the
3859
+ latch is created. Threads can block on the latch object, waiting for
3860
+ counter to be decremented to zero.
3861
+
3862
+ Concurrent invocations of the member functions of `latch`, other than
3863
+ its destructor, do not introduce data races.
3864
+
3865
+ ``` cpp
3866
+ static constexpr ptrdiff_t max() noexcept;
3867
+ ```
3868
+
3869
+ *Returns:* The maximum value of `counter` that the implementation
3870
+ supports.
3871
+
3872
+ ``` cpp
3873
+ constexpr explicit latch(ptrdiff_t expected);
3874
+ ```
3875
+
3876
+ *Preconditions:* `expected >= 0` is `true` and `expected <= max()` is
3877
+ `true`.
3878
+
3879
+ *Effects:* Initializes `counter` with `expected`.
3880
+
3881
+ *Throws:* Nothing.
3882
+
3883
+ ``` cpp
3884
+ void count_down(ptrdiff_t update = 1);
3885
+ ```
3886
+
3887
+ *Preconditions:* `update >= 0` is `true`, and `update <= counter` is
3888
+ `true`.
3889
+
3890
+ *Effects:* Atomically decrements `counter` by `update`. If `counter` is
3891
+ equal to zero, unblocks all threads blocked on `*this`.
3892
+
3893
+ *Synchronization:* Strongly happens before the returns from all calls
3894
+ that are unblocked.
3895
+
3896
+ *Throws:* `system_error` when an exception is
3897
+ required [[thread.req.exception]].
3898
+
3899
+ *Error conditions:* Any of the error conditions allowed for mutex
3900
+ types [[thread.mutex.requirements.mutex]].
3901
+
3902
+ ``` cpp
3903
+ bool try_wait() const noexcept;
3904
+ ```
3905
+
3906
+ *Returns:* With very low probability `false`. Otherwise `counter == 0`.
3907
+
3908
+ ``` cpp
3909
+ void wait() const;
3910
+ ```
3911
+
3912
+ *Effects:* If `counter` equals zero, returns immediately. Otherwise,
3913
+ blocks on `*this` until a call to `count_down` that decrements `counter`
3914
+ to zero.
3915
+
3916
+ *Throws:* `system_error` when an exception is
3917
+ required [[thread.req.exception]].
3918
+
3919
+ *Error conditions:* Any of the error conditions allowed for mutex
3920
+ types [[thread.mutex.requirements.mutex]].
3921
+
3922
+ ``` cpp
3923
+ void arrive_and_wait(ptrdiff_t update = 1);
3924
+ ```
3925
+
3926
+ *Effects:* Equivalent to:
3927
+
3928
+ ``` cpp
3929
+ count_down(update);
3930
+ wait();
3931
+ ```
3932
+
3933
+ ### Barriers <a id="thread.barrier">[[thread.barrier]]</a>
3934
+
3935
+ A barrier is a thread coordination mechanism whose lifetime consists of
3936
+ a sequence of barrier phases, where each phase allows at most an
3937
+ expected number of threads to block until the expected number of threads
3938
+ arrive at the barrier.
3939
+
3940
+ [*Note 1*: A barrier is useful for managing repeated tasks that are
3941
+ handled by multiple threads. — *end note*]
3942
+
3943
+ #### Header `<barrier>` synopsis <a id="barrier.syn">[[barrier.syn]]</a>
3944
+
3945
+ ``` cpp
3946
+ namespace std {
3947
+ template<class CompletionFunction = see below>
3948
+ class barrier;
3949
+ }
3950
+ ```
3951
+
3952
+ #### Class template `barrier` <a id="thread.barrier.class">[[thread.barrier.class]]</a>
3953
+
3954
+ ``` cpp
3955
+ namespace std {
3956
+ template<class CompletionFunction = see below>
3957
+ class barrier {
3958
+ public:
3959
+ using arrival_token = see below;
3960
+
3961
+ static constexpr ptrdiff_t max() noexcept;
3962
+
3963
+ constexpr explicit barrier(ptrdiff_t expected,
3964
+ CompletionFunction f = CompletionFunction());
3965
+ ~barrier();
3966
+
3967
+ barrier(const barrier&) = delete;
3968
+ barrier& operator=(const barrier&) = delete;
3969
+
3970
+ [[nodiscard]] arrival_token arrive(ptrdiff_t update = 1);
3971
+ void wait(arrival_token&& arrival) const;
3972
+
3973
+ void arrive_and_wait();
3974
+ void arrive_and_drop();
3975
+
3976
+ private:
3977
+ CompletionFunction completion; // exposition only
3978
+ };
3979
+ }
3980
+ ```
3981
+
3982
+ Each *barrier phase* consists of the following steps:
3983
+
3984
+ - The expected count is decremented by each call to `arrive` or
3985
+ `arrive_and_drop`.
3986
+ - When the expected count reaches zero, the phase completion step is
3987
+ run. For the specialization with the default value of the
3988
+ `CompletionFunction` template parameter, the completion step is run as
3989
+ part of the call to `arrive` or `arrive_and_drop` that caused the
3990
+ expected count to reach zero. For other specializations, the
3991
+ completion step is run on one of the threads that arrived at the
3992
+ barrier during the phase.
3993
+ - When the completion step finishes, the expected count is reset to what
3994
+ was specified by the `expected` argument to the constructor, possibly
3995
+ adjusted by calls to `arrive_and_drop`, and the next phase starts.
3996
+
3997
+ Each phase defines a *phase synchronization point*. Threads that arrive
3998
+ at the barrier during the phase can block on the phase synchronization
3999
+ point by calling `wait`, and will remain blocked until the phase
4000
+ completion step is run.
4001
+
4002
+ The *phase completion step* that is executed at the end of each phase
4003
+ has the following effects:
4004
+
4005
+ - Invokes the completion function, equivalent to `completion()`.
4006
+ - Unblocks all threads that are blocked on the phase synchronization
4007
+ point.
4008
+
4009
+ The end of the completion step strongly happens before the returns from
4010
+ all calls that were unblocked by the completion step. For
4011
+ specializations that do not have the default value of the
4012
+ `CompletionFunction` template parameter, the behavior is undefined if
4013
+ any of the barrier object’s member functions other than `wait` are
4014
+ called while the completion step is in progress.
4015
+
4016
+ Concurrent invocations of the member functions of `barrier`, other than
4017
+ its destructor, do not introduce data races. The member functions
4018
+ `arrive` and `arrive_and_drop` execute atomically.
4019
+
4020
+ `CompletionFunction` shall meet the *Cpp17MoveConstructible* (
4021
+ [[cpp17.moveconstructible]]) and *Cpp17Destructible* (
4022
+ [[cpp17.destructible]]) requirements.
4023
+ `is_nothrow_invocable_v<CompletionFunction&>` shall be `true`.
4024
+
4025
+ The default value of the `CompletionFunction` template parameter is an
4026
+ unspecified type, such that, in addition to satisfying the requirements
4027
+ of `CompletionFunction`, it meets the *Cpp17DefaultConstructible*
4028
+ requirements ([[cpp17.defaultconstructible]]) and `completion()` has no
4029
+ effects.
4030
+
4031
+ `barrier::arrival_token` is an unspecified type, such that it meets the
4032
+ *Cpp17MoveConstructible* ([[cpp17.moveconstructible]]),
4033
+ *Cpp17MoveAssignable* ([[cpp17.moveassignable]]), and
4034
+ *Cpp17Destructible* ([[cpp17.destructible]]) requirements.
4035
+
4036
+ ``` cpp
4037
+ static constexpr ptrdiff_t max() noexcept;
4038
+ ```
4039
+
4040
+ *Returns:* The maximum expected count that the implementation supports.
4041
+
4042
+ ``` cpp
4043
+ constexpr explicit barrier(ptrdiff_t expected,
4044
+ CompletionFunction f = CompletionFunction());
4045
+ ```
4046
+
4047
+ *Preconditions:* `expected >= 0` is `true` and `expected <= max()` is
4048
+ `true`.
4049
+
4050
+ *Effects:* Sets both the initial expected count for each barrier phase
4051
+ and the current expected count for the first phase to `expected`.
4052
+ Initializes `completion` with `std::move(f)`. Starts the first phase.
4053
+
4054
+ [*Note 1*: If `expected` is 0 this object can only be
4055
+ destroyed. — *end note*]
4056
+
4057
+ *Throws:* Any exception thrown by `CompletionFunction`’s move
4058
+ constructor.
4059
+
4060
+ ``` cpp
4061
+ [[nodiscard]] arrival_token arrive(ptrdiff_t update = 1);
4062
+ ```
4063
+
4064
+ *Preconditions:* `update > 0` is `true`, and `update` is less than or
4065
+ equal to the expected count for the current barrier phase.
4066
+
4067
+ *Effects:* Constructs an object of type `arrival_token` that is
4068
+ associated with the phase synchronization point for the current phase.
4069
+ Then, decrements the expected count by `update`.
4070
+
4071
+ *Synchronization:* The call to `arrive` strongly happens before the
4072
+ start of the phase completion step for the current phase.
4073
+
4074
+ *Returns:* The constructed `arrival_token` object.
4075
+
4076
+ *Throws:* `system_error` when an exception is
4077
+ required [[thread.req.exception]].
4078
+
4079
+ *Error conditions:* Any of the error conditions allowed for mutex
4080
+ types [[thread.mutex.requirements.mutex]].
4081
+
4082
+ [*Note 2*: This call can cause the completion step for the current
4083
+ phase to start. — *end note*]
4084
+
4085
+ ``` cpp
4086
+ void wait(arrival_token&& arrival) const;
4087
+ ```
4088
+
4089
+ *Preconditions:* `arrival` is associated with the phase synchronization
4090
+ point for the current phase or the immediately preceding phase of the
4091
+ same barrier object.
4092
+
4093
+ *Effects:* Blocks at the synchronization point associated with
4094
+ `std::move(arrival)` until the phase completion step of the
4095
+ synchronization point’s phase is run.
4096
+
4097
+ [*Note 3*: If `arrival` is associated with the synchronization point
4098
+ for a previous phase, the call returns immediately. — *end note*]
4099
+
4100
+ *Throws:* `system_error` when an exception is
4101
+ required [[thread.req.exception]].
4102
+
4103
+ *Error conditions:* Any of the error conditions allowed for mutex
4104
+ types [[thread.mutex.requirements.mutex]].
4105
+
4106
+ ``` cpp
4107
+ void arrive_and_wait();
4108
+ ```
4109
+
4110
+ *Effects:* Equivalent to: `wait(arrive())`.
4111
+
4112
+ ``` cpp
4113
+ void arrive_and_drop();
4114
+ ```
4115
+
4116
+ *Preconditions:* The expected count for the current barrier phase is
4117
+ greater than zero.
4118
+
4119
+ *Effects:* Decrements the initial expected count for all subsequent
4120
+ phases by one. Then decrements the expected count for the current phase
4121
+ by one.
4122
+
4123
+ *Synchronization:* The call to `arrive_and_drop` strongly happens before
4124
+ the start of the phase completion step for the current phase.
4125
+
4126
+ *Throws:* `system_error` when an exception is
4127
+ required [[thread.req.exception]].
4128
+
4129
+ *Error conditions:* Any of the error conditions allowed for mutex
4130
+ types [[thread.mutex.requirements.mutex]].
4131
+
4132
+ [*Note 4*: This call can cause the completion step for the current
4133
+ phase to start. — *end note*]
4134
+
4135
  ## Futures <a id="futures">[[futures]]</a>
4136
 
4137
  ### Overview <a id="futures.overview">[[futures.overview]]</a>
4138
 
4139
  [[futures]] describes components that a C++ program can use to retrieve
 
4198
  class packaged_task<R(ArgTypes...)>;
4199
 
4200
  template<class R, class... ArgTypes>
4201
  void swap(packaged_task<R(ArgTypes...)>&, packaged_task<R(ArgTypes...)>&) noexcept;
4202
 
 
 
 
4203
  template<class F, class... Args>
4204
+ [[nodiscard]] future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
4205
  async(F&& f, Args&&... args);
4206
  template<class F, class... Args>
4207
+ [[nodiscard]] future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
4208
  async(launch policy, F&& f, Args&&... args);
4209
  }
4210
  ```
4211
 
4212
+ The `enum` type `launch` is a bitmask type [[bitmask.types]] with
4213
  elements `launch::async` and `launch::deferred`.
4214
 
4215
  [*Note 1*: Implementations can provide bitmasks to specify restrictions
4216
  on task interaction by functions launched by `async()` applicable to a
4217
  corresponding subset of available launch policies. Implementations can
 
4224
 
4225
  ``` cpp
4226
  const error_category& future_category() noexcept;
4227
  ```
4228
 
4229
+ *Returns:* A reference to an object of a type derived from class
4230
  `error_category`.
4231
 
4232
  The object’s `default_error_condition` and equivalent virtual functions
4233
  shall behave as specified for the class `error_category`. The object’s
4234
+ `name` virtual function returns a pointer to the string `"future"`.
4235
 
4236
  ``` cpp
4237
  error_code make_error_code(future_errc e) noexcept;
4238
  ```
4239
 
 
4243
  error_condition make_error_condition(future_errc e) noexcept;
4244
  ```
4245
 
4246
  *Returns:* `error_condition(static_cast<int>(e), future_category())`.
4247
 
4248
+ ### Class `future_error` <a id="futures.future.error">[[futures.future.error]]</a>
4249
 
4250
  ``` cpp
4251
  namespace std {
4252
  class future_error : public logic_error {
4253
  public:
4254
  explicit future_error(future_errc e);
4255
 
4256
  const error_code& code() const noexcept;
4257
  const char* what() const noexcept;
4258
+
4259
  private:
4260
  error_code ec_; // exposition only
4261
  };
4262
  }
4263
  ```
4264
 
4265
  ``` cpp
4266
  explicit future_error(future_errc e);
4267
  ```
4268
 
4269
+ *Effects:* Initializes `ec_` with `make_error_code(e)`.
 
4270
 
4271
  ``` cpp
4272
  const error_code& code() const noexcept;
4273
  ```
4274
 
 
4280
 
4281
  *Returns:* An NTBS incorporating `code().message()`.
4282
 
4283
  ### Shared state <a id="futures.state">[[futures.state]]</a>
4284
 
4285
+ Many of the classes introduced in subclause  [[futures]] use some state
4286
+ to communicate results. This *shared state* consists of some state
4287
  information and some (possibly not yet evaluated) *result*, which can be
4288
  a (possibly void) value or an exception.
4289
 
4290
  [*Note 1*: Futures, promises, and tasks defined in this clause
4291
  reference such shared state. — *end note*]
 
4296
 
4297
  An *asynchronous return object* is an object that reads results from a
4298
  shared state. A *waiting function* of an asynchronous return object is
4299
  one that potentially blocks to wait for the shared state to be made
4300
  ready. If a waiting function can return before the state is made ready
4301
+ because of a timeout [[thread.req.lockable]], then it is a *timed
4302
  waiting function*, otherwise it is a *non-timed waiting function*.
4303
 
4304
  An *asynchronous provider* is an object that provides a result to a
4305
  shared state. The result of a shared state is set by respective
4306
  functions on the asynchronous provider.
 
4343
  for retrieval. Waiting for a shared state to become ready may invoke
4344
  code to compute the result on the waiting thread if so specified in the
4345
  description of the class or function that creates the state object.
4346
 
4347
  Calls to functions that successfully set the stored result of a shared
4348
+ state synchronize with [[intro.multithread]] calls to functions
4349
  successfully detecting the ready state resulting from that setting. The
4350
  storage of the result (whether normal or exceptional) into the shared
4351
+ state synchronizes with [[intro.multithread]] the successful return from
4352
+ a call to a waiting function on the shared state.
4353
 
4354
  Some functions (e.g., `promise::set_value_at_thread_exit`) delay making
4355
  the shared state ready until the calling thread exits. The destruction
4356
+ of each of that thread’s objects with thread storage duration
4357
+ [[basic.stc.thread]] is sequenced before making that shared state ready.
 
4358
 
4359
+ Access to the result of the same shared state may conflict
4360
+ [[intro.multithread]].
4361
 
4362
  [*Note 4*: This explicitly specifies that the result of the shared
4363
  state is visible in the objects that reference this state in the sense
4364
+ of data race avoidance [[res.on.data.races]]. For example, concurrent
4365
+ accesses through references returned by `shared_future::get()`
4366
+ [[futures.shared.future]] must either use read-only operations or
4367
  provide additional synchronization. — *end note*]
4368
 
4369
  ### Class template `promise` <a id="futures.promise">[[futures.promise]]</a>
4370
 
4371
  ``` cpp
 
4375
  public:
4376
  promise();
4377
  template<class Allocator>
4378
  promise(allocator_arg_t, const Allocator& a);
4379
  promise(promise&& rhs) noexcept;
4380
+ promise(const promise&) = delete;
4381
  ~promise();
4382
 
4383
  // assignment
4384
  promise& operator=(promise&& rhs) noexcept;
4385
+ promise& operator=(const promise&) = delete;
4386
  void swap(promise& other) noexcept;
4387
 
4388
  // retrieving the result
4389
  future<R> get_future();
4390
 
 
4394
 
4395
  // setting the result with deferred notification
4396
  void set_value_at_thread_exit(see below);
4397
  void set_exception_at_thread_exit(exception_ptr p);
4398
  };
4399
+
4400
  template<class R>
4401
  void swap(promise<R>& x, promise<R>& y) noexcept;
4402
+
4403
  template<class R, class Alloc>
4404
  struct uses_allocator<promise<R>, Alloc>;
4405
  }
4406
  ```
4407
 
4408
+ The implementation provides the template `promise` and two
4409
  specializations, `promise<R&>` and `promise<{}void>`. These differ only
4410
  in the argument type of the member functions `set_value` and
4411
  `set_value_at_thread_exit`, as set out in their descriptions, below.
4412
 
4413
  The `set_value`, `set_exception`, `set_value_at_thread_exit`, and
 
4419
  template<class R, class Alloc>
4420
  struct uses_allocator<promise<R>, Alloc>
4421
  : true_type { };
4422
  ```
4423
 
4424
+ *Preconditions:* `Alloc` meets the *Cpp17Allocator* requirements
4425
+ ([[cpp17.allocator]]).
4426
 
4427
  ``` cpp
4428
  promise();
4429
  template<class Allocator>
4430
  promise(allocator_arg_t, const Allocator& a);
4431
  ```
4432
 
4433
+ *Effects:* Creates a shared state. The second constructor uses the
4434
+ allocator `a` to allocate memory for the shared state.
 
4435
 
4436
  ``` cpp
4437
  promise(promise&& rhs) noexcept;
4438
  ```
4439
 
4440
+ *Effects:* Transfers ownership of the shared state of `rhs` (if any) to
4441
+ the newly-constructed object.
4442
 
4443
+ *Ensures:* `rhs` has no shared state.
4444
 
4445
  ``` cpp
4446
  ~promise();
4447
  ```
4448
 
4449
+ *Effects:* Abandons any shared state [[futures.state]].
4450
 
4451
  ``` cpp
4452
  promise& operator=(promise&& rhs) noexcept;
4453
  ```
4454
 
4455
+ *Effects:* Abandons any shared state [[futures.state]] and then as if
4456
  `promise(std::move(rhs)).swap(*this)`.
4457
 
4458
  *Returns:* `*this`.
4459
 
4460
  ``` cpp
4461
  void swap(promise& other) noexcept;
4462
  ```
4463
 
4464
  *Effects:* Exchanges the shared state of `*this` and `other`.
4465
 
4466
+ *Ensures:* `*this` has the shared state (if any) that `other` had prior
4467
+ to the call to `swap`. `other` has the shared state (if any) that
4468
  `*this` had prior to the call to `swap`.
4469
 
4470
  ``` cpp
4471
  future<R> get_future();
4472
  ```
4473
 
4474
  *Returns:* A `future<R>` object with the same shared state as `*this`.
4475
 
4476
+ *Synchronization:* Calls to this function do not introduce data
4477
+ races  [[intro.multithread]] with calls to `set_value`, `set_exception`,
4478
+ `set_value_at_thread_exit`, or `set_exception_at_thread_exit`.
4479
+
4480
+ [*Note 1*: Such calls need not synchronize with each
4481
+ other. — *end note*]
4482
+
4483
  *Throws:* `future_error` if `*this` has no shared state or if
4484
  `get_future` has already been called on a `promise` with the same shared
4485
  state as `*this`.
4486
 
4487
  *Error conditions:*
 
4496
  void promise<R&>::set_value(R& r);
4497
  void promise<void>::set_value();
4498
  ```
4499
 
4500
  *Effects:* Atomically stores the value `r` in the shared state and makes
4501
+ that state ready [[futures.state]].
4502
 
4503
  *Throws:*
4504
 
4505
  - `future_error` if its shared state already has a stored value or
4506
  exception, or
 
4517
 
4518
  ``` cpp
4519
  void set_exception(exception_ptr p);
4520
  ```
4521
 
4522
+ *Preconditions:* `p` is not null.
4523
 
4524
  *Effects:* Atomically stores the exception pointer `p` in the shared
4525
+ state and makes that state ready [[futures.state]].
4526
 
4527
  *Throws:* `future_error` if its shared state already has a stored value
4528
  or exception.
4529
 
4530
  *Error conditions:*
 
4562
 
4563
  ``` cpp
4564
  void set_exception_at_thread_exit(exception_ptr p);
4565
  ```
4566
 
4567
+ *Preconditions:* `p` is not null.
4568
 
4569
  *Effects:* Stores the exception pointer `p` in the shared state without
4570
  making that state ready immediately. Schedules that state to be made
4571
  ready when the current thread exits, after all objects of thread storage
4572
  duration associated with the current thread have been destroyed.
 
4584
  void swap(promise<R>& x, promise<R>& y) noexcept;
4585
  ```
4586
 
4587
  *Effects:* As if by `x.swap(y)`.
4588
 
4589
+ ### Class template `future` <a id="futures.unique.future">[[futures.unique.future]]</a>
4590
 
4591
  The class template `future` defines a type for asynchronous return
4592
  objects which do not share their shared state with other asynchronous
4593
  return objects. A default-constructed `future` object has no shared
4594
  state. A `future` object with shared state can be created by functions
4595
+ on asynchronous providers [[futures.state]] or by the move constructor
4596
+ and shares its shared state with the original asynchronous provider. The
4597
+ result (value or exception) of a `future` object can be set by calling a
4598
+ respective function on an object that shares the same shared state.
 
4599
 
4600
  [*Note 1*: Member functions of `future` do not synchronize with
4601
  themselves or with member functions of `shared_future`. — *end note*]
4602
 
4603
  The effect of calling any member function other than the destructor, the
 
4605
  which `valid() == false` is undefined.
4606
 
4607
  [*Note 2*: It is valid to move from a future object for which
4608
  `valid() == false`. — *end note*]
4609
 
4610
+ [*Note 3*: Implementations should detect this case and throw an object
4611
+ of type `future_error` with an error condition of
4612
  `future_errc::no_state`. — *end note*]
4613
 
4614
  ``` cpp
4615
  namespace std {
4616
  template<class R>
4617
  class future {
4618
  public:
4619
  future() noexcept;
4620
  future(future&&) noexcept;
4621
+ future(const future&) = delete;
4622
  ~future();
4623
+ future& operator=(const future&) = delete;
4624
  future& operator=(future&&) noexcept;
4625
  shared_future<R> share() noexcept;
4626
 
4627
  // retrieving the value
4628
  see below get();
 
4637
  future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
4638
  };
4639
  }
4640
  ```
4641
 
4642
+ The implementation provides the template `future` and two
4643
  specializations, `future<R&>` and `future<{}void>`. These differ only in
4644
  the return type and return value of the member function `get`, as set
4645
  out in its description, below.
4646
 
4647
  ``` cpp
4648
  future() noexcept;
4649
  ```
4650
 
4651
+ *Effects:* The object does not refer to a shared state.
 
4652
 
4653
+ *Ensures:* `valid() == false`.
4654
 
4655
  ``` cpp
4656
  future(future&& rhs) noexcept;
4657
  ```
4658
 
4659
  *Effects:* Move constructs a `future` object that refers to the shared
4660
  state that was originally referred to by `rhs` (if any).
4661
 
4662
+ *Ensures:*
4663
 
4664
  - `valid()` returns the same value as `rhs.valid()` prior to the
4665
  constructor invocation.
4666
  - `rhs.valid() == false`.
4667
 
 
4669
  ~future();
4670
  ```
4671
 
4672
  *Effects:*
4673
 
4674
+ - Releases any shared state [[futures.state]];
4675
  - destroys `*this`.
4676
 
4677
  ``` cpp
4678
  future& operator=(future&& rhs) noexcept;
4679
  ```
4680
 
4681
  *Effects:*
4682
 
4683
+ - Releases any shared state [[futures.state]].
4684
  - move assigns the contents of `rhs` to `*this`.
4685
 
4686
+ *Ensures:*
4687
 
4688
  - `valid()` returns the same value as `rhs.valid()` prior to the
4689
  assignment.
4690
  - `rhs.valid() == false`.
4691
 
 
4693
  shared_future<R> share() noexcept;
4694
  ```
4695
 
4696
  *Returns:* `shared_future<R>(std::move(*this))`.
4697
 
4698
+ *Ensures:* `valid() == false`.
4699
 
4700
  ``` cpp
4701
  R future::get();
4702
  R& future<R&>::get();
4703
  void future<void>::get();
 
4709
 
4710
  *Effects:*
4711
 
4712
  - `wait()`s until the shared state is ready, then retrieves the value
4713
  stored in the shared state;
4714
+ - releases any shared state [[futures.state]].
4715
 
4716
  *Returns:*
4717
 
4718
  - `future::get()` returns the value `v` stored in the object’s shared
4719
  state as `std::move(v)`.
4720
  - `future<R&>::get()` returns the reference stored as value in the
4721
  object’s shared state.
4722
  - `future<void>::get()` returns nothing.
4723
 
4724
+ *Throws:* The stored exception, if an exception was stored in the shared
4725
  state.
4726
 
4727
+ *Ensures:* `valid() == false`.
4728
 
4729
  ``` cpp
4730
  bool valid() const noexcept;
4731
  ```
4732
 
 
4742
  template<class Rep, class Period>
4743
  future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
4744
  ```
4745
 
4746
  *Effects:* None if the shared state contains a deferred
4747
+ function [[futures.async]], otherwise blocks until the shared state is
4748
+ ready or until the relative timeout [[thread.req.timing]] specified by
4749
+ `rel_time` has expired.
4750
 
4751
  *Returns:*
4752
 
4753
  - `future_status::deferred` if the shared state contains a deferred
4754
  function.
4755
  - `future_status::ready` if the shared state is ready.
4756
  - `future_status::timeout` if the function is returning because the
4757
+ relative timeout [[thread.req.timing]] specified by `rel_time` has
4758
  expired.
4759
 
4760
+ *Throws:* timeout-related exceptions [[thread.req.timing]].
4761
 
4762
  ``` cpp
4763
  template<class Clock, class Duration>
4764
  future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
4765
  ```
4766
 
4767
  *Effects:* None if the shared state contains a deferred
4768
+ function [[futures.async]], otherwise blocks until the shared state is
4769
+ ready or until the absolute timeout [[thread.req.timing]] specified by
4770
+ `abs_time` has expired.
4771
 
4772
  *Returns:*
4773
 
4774
  - `future_status::deferred` if the shared state contains a deferred
4775
  function.
4776
  - `future_status::ready` if the shared state is ready.
4777
  - `future_status::timeout` if the function is returning because the
4778
+ absolute timeout [[thread.req.timing]] specified by `abs_time` has
4779
  expired.
4780
 
4781
+ *Throws:* timeout-related exceptions [[thread.req.timing]].
4782
 
4783
+ ### Class template `shared_future` <a id="futures.shared.future">[[futures.shared.future]]</a>
4784
 
4785
  The class template `shared_future` defines a type for asynchronous
4786
  return objects which may share their shared state with other
4787
  asynchronous return objects. A default-constructed `shared_future`
4788
  object has no shared state. A `shared_future` object with shared state
4789
  can be created by conversion from a `future` object and shares its
4790
+ shared state with the original asynchronous provider [[futures.state]]
4791
+ of the shared state. The result (value or exception) of a
4792
+ `shared_future` object can be set by calling a respective function on an
4793
+ object that shares the same shared state.
4794
 
4795
  [*Note 1*: Member functions of `shared_future` do not synchronize with
4796
  themselves, but they synchronize with the shared state. — *end note*]
4797
 
4798
  The effect of calling any member function other than the destructor, the
 
4800
  a `shared_future` object for which `valid() == false` is undefined.
4801
 
4802
  [*Note 2*: It is valid to copy or move from a `shared_future` object
4803
  for which `valid()` is `false`. — *end note*]
4804
 
4805
+ [*Note 3*: Implementations should detect this case and throw an object
4806
+ of type `future_error` with an error condition of
4807
  `future_errc::no_state`. — *end note*]
4808
 
4809
  ``` cpp
4810
  namespace std {
4811
  template<class R>
 
4832
  future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
4833
  };
4834
  }
4835
  ```
4836
 
4837
+ The implementation provides the template `shared_future` and two
4838
  specializations, `shared_future<R&>` and `shared_future<void>`. These
4839
  differ only in the return type and return value of the member function
4840
  `get`, as set out in its description, below.
4841
 
4842
  ``` cpp
4843
  shared_future() noexcept;
4844
  ```
4845
 
4846
+ *Effects:* The object does not refer to a shared state.
 
4847
 
4848
+ *Ensures:* `valid() == false`.
4849
 
4850
  ``` cpp
4851
  shared_future(const shared_future& rhs) noexcept;
4852
  ```
4853
 
4854
+ *Effects:* The object refers to the same shared state as `rhs` (if any).
 
4855
 
4856
+ *Ensures:* `valid()` returns the same value as `rhs.valid()`.
4857
 
4858
  ``` cpp
4859
  shared_future(future<R>&& rhs) noexcept;
4860
  shared_future(shared_future&& rhs) noexcept;
4861
  ```
4862
 
4863
  *Effects:* Move constructs a `shared_future` object that refers to the
4864
  shared state that was originally referred to by `rhs` (if any).
4865
 
4866
+ *Ensures:*
4867
 
4868
  - `valid()` returns the same value as `rhs.valid()` returned prior to
4869
  the constructor invocation.
4870
  - `rhs.valid() == false`.
4871
 
 
4873
  ~shared_future();
4874
  ```
4875
 
4876
  *Effects:*
4877
 
4878
+ - Releases any shared state [[futures.state]];
4879
  - destroys `*this`.
4880
 
4881
  ``` cpp
4882
  shared_future& operator=(shared_future&& rhs) noexcept;
4883
  ```
4884
 
4885
  *Effects:*
4886
 
4887
+ - Releases any shared state [[futures.state]];
4888
  - move assigns the contents of `rhs` to `*this`.
4889
 
4890
+ *Ensures:*
4891
 
4892
  - `valid()` returns the same value as `rhs.valid()` returned prior to
4893
  the assignment.
4894
  - `rhs.valid() == false`.
4895
 
 
4897
  shared_future& operator=(const shared_future& rhs) noexcept;
4898
  ```
4899
 
4900
  *Effects:*
4901
 
4902
+ - Releases any shared state [[futures.state]];
4903
  - assigns the contents of `rhs` to `*this`. \[*Note 4*: As a result,
4904
  `*this` refers to the same shared state as `rhs` (if
4905
  any). — *end note*]
4906
 
4907
+ *Ensures:* `valid() == rhs.valid()`.
4908
 
4909
  ``` cpp
4910
  const R& shared_future::get() const;
4911
  R& shared_future<R&>::get() const;
4912
  void shared_future<void>::get() const;
 
4916
  specializations differ only in the return type and return value of the
4917
  member function `get`. — *end note*]
4918
 
4919
  [*Note 2*: Access to a value object stored in the shared state is
4920
  unsynchronized, so programmers should apply only those operations on `R`
4921
+ that do not introduce a data race [[intro.multithread]]. — *end note*]
 
4922
 
4923
  *Effects:* `wait()`s until the shared state is ready, then retrieves the
4924
  value stored in the shared state.
4925
 
4926
  *Returns:*
 
4933
  returned the reference. — *end note*]
4934
  - `shared_future<R&>::get()` returns the reference stored as value in
4935
  the object’s shared state.
4936
  - `shared_future<void>::get()` returns nothing.
4937
 
4938
+ *Throws:* The stored exception, if an exception was stored in the shared
4939
  state.
4940
 
4941
  ``` cpp
4942
  bool valid() const noexcept;
4943
  ```
 
4954
  template<class Rep, class Period>
4955
  future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
4956
  ```
4957
 
4958
  *Effects:* None if the shared state contains a deferred
4959
+ function [[futures.async]], otherwise blocks until the shared state is
4960
+ ready or until the relative timeout [[thread.req.timing]] specified by
4961
+ `rel_time` has expired.
4962
 
4963
  *Returns:*
4964
 
4965
  - `future_status::deferred` if the shared state contains a deferred
4966
  function.
4967
  - `future_status::ready` if the shared state is ready.
4968
  - `future_status::timeout` if the function is returning because the
4969
+ relative timeout [[thread.req.timing]] specified by `rel_time` has
4970
  expired.
4971
 
4972
+ *Throws:* timeout-related exceptions [[thread.req.timing]].
4973
 
4974
  ``` cpp
4975
  template<class Clock, class Duration>
4976
  future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
4977
  ```
4978
 
4979
  *Effects:* None if the shared state contains a deferred
4980
+ function [[futures.async]], otherwise blocks until the shared state is
4981
+ ready or until the absolute timeout [[thread.req.timing]] specified by
4982
+ `abs_time` has expired.
4983
 
4984
  *Returns:*
4985
 
4986
  - `future_status::deferred` if the shared state contains a deferred
4987
  function.
4988
  - `future_status::ready` if the shared state is ready.
4989
  - `future_status::timeout` if the function is returning because the
4990
+ absolute timeout [[thread.req.timing]] specified by `abs_time` has
4991
  expired.
4992
 
4993
+ *Throws:* timeout-related exceptions [[thread.req.timing]].
4994
 
4995
  ### Function template `async` <a id="futures.async">[[futures.async]]</a>
4996
 
4997
  The function template `async` provides a mechanism to launch a function
4998
  potentially in a new thread and provides the result of the function in a
4999
  `future` object with which it shares a shared state.
5000
 
5001
  ``` cpp
5002
  template<class F, class... Args>
5003
+ [[nodiscard]] future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
5004
  async(F&& f, Args&&... args);
5005
  template<class F, class... Args>
5006
+ [[nodiscard]] future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
5007
  async(launch policy, F&& f, Args&&... args);
5008
  ```
5009
 
5010
+ *Mandates:* The following are all `true`:
 
5011
 
5012
+ - `is_constructible_v<decay_t<F>, F>`,
5013
+ - `(is_constructible_v<decay_t<Args>, Args> &&...)`,
5014
+ - `is_move_constructible_v<decay_t<F>>`,
5015
+ - `(is_move_constructible_v<decay_t<Args>> &&...)`, and
5016
+ - `is_invocable_v<decay_t<F>, decay_t<Args>...>`.
5017
 
5018
+ *Preconditions:* `decay_t<F>` and each type in `decay_t<Args>` meet the
5019
+ *Cpp17MoveConstructible* requirements.
5020
 
5021
  *Effects:* The first function behaves the same as a call to the second
5022
  function with a `policy` argument of `launch::async | launch::deferred`
5023
  and the same arguments for `F` and `Args`. The second function creates a
5024
  shared state that is associated with the returned `future` object. The
5025
  further behavior of the second function depends on the `policy` argument
5026
  as follows (if more than one of these conditions applies, the
5027
  implementation may choose any of the corresponding policies):
5028
 
5029
  - If `launch::async` is set in `policy`, calls
5030
+ `invoke(`*`decay-copy`*`(std::forward<F>(f)),`
5031
+ *decay-copy*(std::forward\<Args\>(args))...) ([[func.require]],
5032
  [[thread.thread.constr]]) as if in a new thread of execution
5033
+ represented by a `thread` object with the calls to *`decay-copy`*
5034
  being evaluated in the thread that called `async`. Any return value is
5035
  stored as the result in the shared state. Any exception propagated
5036
+ from the execution of
5037
+ `invoke(`*`decay-copy`*`(std::forward<F>(f)), `*`decay-copy`*`(std::forward<Args>(args))...)`
5038
+ is stored as the exceptional result in the shared state. The `thread`
5039
+ object is stored in the shared state and affects the behavior of any
5040
+ asynchronous return objects that reference that state.
5041
  - If `launch::deferred` is set in `policy`, stores
5042
+ *decay-copy*(std::forward\<F\>(f)) and
5043
+ *decay-copy*(std::forward\<Args\>(args))... in the shared state. These
5044
  copies of `f` and `args` constitute a *deferred function*. Invocation
5045
+ of the deferred function evaluates
5046
+ `invoke(std::move(g), std::move(xyz))` where `g` is the stored value
5047
+ of *decay-copy*(std::forward\<F\>(f)) and `xyz` is the stored copy of
5048
+ *decay-copy*(std::forward\<Args\>(args)).... Any return value is
5049
  stored as the result in the shared state. Any exception propagated
5050
  from the execution of the deferred function is stored as the
5051
  exceptional result in the shared state. The shared state is not made
5052
  ready until the function has completed. The first call to a non-timed
5053
+ waiting function [[futures.state]] on an asynchronous return object
5054
+ referring to this shared state invokes the deferred function in the
5055
+ thread that called the waiting function. Once evaluation of
5056
+ `invoke(std::move(g), std::move(xyz))` begins, the function is no
5057
  longer considered deferred. \[*Note 1*: If this policy is specified
5058
  together with other policies, such as when using a `policy` value of
5059
  `launch::async | launch::deferred`, implementations should defer
5060
  invocation or the selection of the policy when no more concurrency can
5061
  be effectively exploited. — *end note*]
5062
  - If no value is set in the launch policy, or a value is set that is
5063
+ neither specified in this document nor by the implementation, the
5064
+ behavior is undefined.
5065
 
5066
  *Returns:* An object of type
5067
  `future<invoke_result_t<decay_t<F>, decay_t<Args>...>``>` that refers to
5068
  the shared state created by this call to `async`.
5069
 
5070
  [*Note 1*: If a future obtained from `async` is moved outside the local
5071
+ scope, other code that uses the future should be aware that the future’s
5072
+ destructor can block for the shared state to become
5073
  ready. — *end note*]
5074
 
5075
  *Synchronization:* Regardless of the provided `policy` argument,
5076
 
5077
+ - the invocation of `async` synchronizes with [[intro.multithread]] the
5078
+ invocation of `f`. \[*Note 2*: This statement applies even when the
5079
+ corresponding `future` object is moved to another
5080
  thread. — *end note*] ; and
5081
  - the completion of the function `f` is sequenced
5082
+ before [[intro.multithread]] the shared state is made ready.
5083
  \[*Note 3*: `f` might not be called at all, so its completion might
5084
  never happen. — *end note*]
5085
 
5086
  If the implementation chooses the `launch::async` policy,
5087
 
5088
  - a call to a waiting function on an asynchronous return object that
5089
  shares the shared state created by this `async` call shall block until
5090
  the associated thread has completed, as if joined, or else time
5091
+ out [[thread.thread.member]];
5092
  - the associated thread completion synchronizes
5093
+ with [[intro.multithread]] the return from the first function that
5094
  successfully detects the ready status of the shared state or with the
5095
  return from the last function that releases the shared state,
5096
  whichever happens first.
5097
 
5098
  *Throws:* `system_error` if `policy == launch::async` and the
 
5152
  void operator()(ArgTypes... );
5153
  void make_ready_at_thread_exit(ArgTypes...);
5154
 
5155
  void reset();
5156
  };
5157
+
5158
  template<class R, class... ArgTypes>
5159
  void swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y) noexcept;
 
 
5160
  }
5161
  ```
5162
 
5163
+ #### Member functions <a id="futures.task.members">[[futures.task.members]]</a>
5164
 
5165
  ``` cpp
5166
  packaged_task() noexcept;
5167
  ```
5168
 
5169
+ *Effects:* The object has no shared state and no stored task.
 
5170
 
5171
  ``` cpp
5172
  template<class F>
5173
  packaged_task(F&& f);
5174
  ```
5175
 
5176
+ *Constraints:* `remove_cvref_t<F>` is not the same type as
5177
+ `packaged_task<R(ArgTypes...)>`.
5178
+
5179
+ *Mandates:* `is_invocable_r_v<R, F&, ArgTypes...>` is `true`.
5180
+
5181
+ *Preconditions:* Invoking a copy of `f` behaves the same as invoking
5182
  `f`.
5183
 
 
 
 
5184
  *Effects:* Constructs a new `packaged_task` object with a shared state
5185
  and initializes the object’s stored task with `std::forward<F>(f)`.
5186
 
5187
+ *Throws:* Any exceptions thrown by the copy or move constructor of `f`,
5188
+ or `bad_alloc` if memory for the internal data structures could not be
5189
+ allocated.
 
 
 
 
 
5190
 
5191
  ``` cpp
5192
  packaged_task(packaged_task&& rhs) noexcept;
5193
  ```
5194
 
5195
+ *Effects:* Transfers ownership of `rhs`’s shared state to `*this`,
5196
+ leaving `rhs` with no shared state. Moves the stored task from `rhs` to
5197
+ `*this`.
5198
 
5199
+ *Ensures:* `rhs` has no shared state.
5200
 
5201
  ``` cpp
5202
  packaged_task& operator=(packaged_task&& rhs) noexcept;
5203
  ```
5204
 
5205
  *Effects:*
5206
 
5207
+ - Releases any shared state [[futures.state]];
5208
  - calls `packaged_task(std::move(rhs)).swap(*this)`.
5209
 
5210
  ``` cpp
5211
  ~packaged_task();
5212
  ```
5213
 
5214
+ *Effects:* Abandons any shared state [[futures.state]].
5215
 
5216
  ``` cpp
5217
  void swap(packaged_task& other) noexcept;
5218
  ```
5219
 
5220
  *Effects:* Exchanges the shared states and stored tasks of `*this` and
5221
  `other`.
5222
 
5223
+ *Ensures:* `*this` has the same shared state and stored task (if any) as
5224
+ `other` prior to the call to `swap`. `other` has the same shared state
5225
+ and stored task (if any) as `*this` prior to the call to `swap`.
5226
 
5227
  ``` cpp
5228
  bool valid() const noexcept;
5229
  ```
5230
 
 
5235
  ```
5236
 
5237
  *Returns:* A `future` object that shares the same shared state as
5238
  `*this`.
5239
 
5240
+ *Synchronization:* Calls to this function do not introduce data
5241
+ races  [[intro.multithread]] with calls to `operator()` or
5242
+ `make_ready_at_thread_exit`.
5243
+
5244
+ [*Note 1*: Such calls need not synchronize with each
5245
+ other. — *end note*]
5246
+
5247
+ *Throws:* A `future_error` object if an error occurs.
5248
 
5249
  *Error conditions:*
5250
 
5251
  - `future_already_retrieved` if `get_future` has already been called on
5252
  a `packaged_task` object with the same shared state as `*this`.
 
5254
 
5255
  ``` cpp
5256
  void operator()(ArgTypes... args);
5257
  ```
5258
 
5259
+ *Effects:* As if by *INVOKE*\<R\>(f, t₁, t₂, , t$_N$) [[func.require]],
5260
+ where `f` is the stored task of `*this` and `t`₁`, t`₂`, `…`, t`$_N$ are
5261
+ the values in `args...`. If the task returns normally, the return value
5262
+ is stored as the asynchronous result in the shared state of `*this`,
5263
+ otherwise the exception thrown by the task is stored. The shared state
5264
+ of `*this` is made ready, and any threads blocked in a function waiting
5265
+ for the shared state of `*this` to become ready are unblocked.
5266
 
5267
+ *Throws:* A `future_error` exception object if there is no shared state
5268
  or the stored task has already been invoked.
5269
 
5270
  *Error conditions:*
5271
 
5272
  - `promise_already_satisfied` if the stored task has already been
 
5275
 
5276
  ``` cpp
5277
  void make_ready_at_thread_exit(ArgTypes... args);
5278
  ```
5279
 
5280
+ *Effects:* As if by *INVOKE*\<R\>(f, t₁, t₂, , t$_N$) [[func.require]],
5281
+ where `f` is the stored task and `t`₁`, t`₂`, `…`, t`$_N$ are the values
5282
+ in `args...`. If the task returns normally, the return value is stored
5283
+ as the asynchronous result in the shared state of `*this`, otherwise the
5284
+ exception thrown by the task is stored. In either case, this is done
5285
+ without making that state ready [[futures.state]] immediately. Schedules
5286
+ the shared state to be made ready when the current thread exits, after
5287
+ all objects of thread storage duration associated with the current
5288
+ thread have been destroyed.
5289
 
5290
  *Throws:* `future_error` if an error condition occurs.
5291
 
5292
  *Error conditions:*
5293
 
 
5300
  ```
5301
 
5302
  *Effects:* As if `*this = packaged_task(std::move(f))`, where `f` is the
5303
  task stored in `*this`.
5304
 
5305
+ [*Note 2*: This constructs a new shared state for `*this`. The old
5306
+ state is abandoned [[futures.state]]. — *end note*]
5307
 
5308
  *Throws:*
5309
 
5310
  - `bad_alloc` if memory for the new shared state could not be allocated.
5311
  - any exception thrown by the move constructor of the task stored in the
5312
  shared state.
5313
  - `future_error` with an error condition of `no_state` if `*this` has no
5314
  shared state.
5315
 
5316
+ #### Globals <a id="futures.task.nonmembers">[[futures.task.nonmembers]]</a>
5317
 
5318
  ``` cpp
5319
  template<class R, class... ArgTypes>
5320
  void swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y) noexcept;
5321
  ```
5322
 
5323
  *Effects:* As if by `x.swap(y)`.
5324
 
 
 
 
 
 
 
 
 
5325
  <!-- Link reference definitions -->
5326
  [alg.sorting]: algorithms.md#alg.sorting
 
5327
  [atomics]: atomics.md#atomics
5328
+ [barrier.syn]: #barrier.syn
5329
  [basic.life]: basic.md#basic.life
5330
  [basic.stc.thread]: basic.md#basic.stc.thread
5331
  [bitmask.types]: library.md#bitmask.types
5332
+ [class.prop]: class.md#class.prop
5333
+ [condition.variable.syn]: #condition.variable.syn
5334
+ [cpp17.allocator]: #cpp17.allocator
5335
+ [cpp17.defaultconstructible]: #cpp17.defaultconstructible
5336
+ [cpp17.destructible]: #cpp17.destructible
5337
+ [cpp17.moveassignable]: #cpp17.moveassignable
5338
+ [cpp17.moveconstructible]: #cpp17.moveconstructible
5339
+ [defns.block]: intro.md#defns.block
5340
  [except.terminate]: except.md#except.terminate
5341
  [func.require]: utilities.md#func.require
5342
  [future.syn]: #future.syn
5343
  [futures]: #futures
5344
  [futures.async]: #futures.async
5345
  [futures.errors]: #futures.errors
5346
+ [futures.future.error]: #futures.future.error
5347
  [futures.overview]: #futures.overview
5348
  [futures.promise]: #futures.promise
5349
+ [futures.shared.future]: #futures.shared.future
5350
  [futures.state]: #futures.state
5351
  [futures.task]: #futures.task
5352
  [futures.task.members]: #futures.task.members
5353
  [futures.task.nonmembers]: #futures.task.nonmembers
5354
+ [futures.unique.future]: #futures.unique.future
5355
+ [intro.multithread]: basic.md#intro.multithread
5356
+ [intro.races]: basic.md#intro.races
5357
+ [latch.syn]: #latch.syn
5358
  [mutex.syn]: #mutex.syn
5359
  [res.on.data.races]: library.md#res.on.data.races
5360
  [res.on.exception.handling]: library.md#res.on.exception.handling
5361
+ [semaphore.syn]: #semaphore.syn
5362
+ [shared.mutex.syn]: #shared.mutex.syn
5363
+ [stopcallback]: #stopcallback
5364
+ [stopcallback.cons]: #stopcallback.cons
5365
+ [stopsource]: #stopsource
5366
+ [stopsource.cons]: #stopsource.cons
5367
+ [stopsource.mem]: #stopsource.mem
5368
+ [stopsource.nonmembers]: #stopsource.nonmembers
5369
+ [stoptoken]: #stoptoken
5370
+ [stoptoken.cons]: #stoptoken.cons
5371
+ [stoptoken.mem]: #stoptoken.mem
5372
+ [stoptoken.nonmembers]: #stoptoken.nonmembers
5373
  [syserr]: diagnostics.md#syserr
5374
  [syserr.syserr]: diagnostics.md#syserr.syserr
 
5375
  [thread]: #thread
5376
+ [thread.barrier]: #thread.barrier
5377
+ [thread.barrier.class]: #thread.barrier.class
5378
  [thread.condition]: #thread.condition
5379
  [thread.condition.condvar]: #thread.condition.condvar
5380
  [thread.condition.condvarany]: #thread.condition.condvarany
5381
  [thread.condition.nonmember]: #thread.condition.nonmember
5382
+ [thread.condvarany.intwait]: #thread.condvarany.intwait
5383
+ [thread.condvarany.wait]: #thread.condvarany.wait
5384
+ [thread.coord]: #thread.coord
5385
  [thread.general]: #thread.general
5386
+ [thread.jthread.class]: #thread.jthread.class
5387
+ [thread.jthread.cons]: #thread.jthread.cons
5388
+ [thread.jthread.mem]: #thread.jthread.mem
5389
+ [thread.jthread.special]: #thread.jthread.special
5390
+ [thread.jthread.static]: #thread.jthread.static
5391
+ [thread.jthread.stop]: #thread.jthread.stop
5392
+ [thread.latch]: #thread.latch
5393
+ [thread.latch.class]: #thread.latch.class
5394
  [thread.lock]: #thread.lock
5395
  [thread.lock.algorithm]: #thread.lock.algorithm
5396
  [thread.lock.guard]: #thread.lock.guard
5397
  [thread.lock.scoped]: #thread.lock.scoped
5398
  [thread.lock.shared]: #thread.lock.shared
 
5422
  [thread.req.lockable.req]: #thread.req.lockable.req
5423
  [thread.req.lockable.timed]: #thread.req.lockable.timed
5424
  [thread.req.native]: #thread.req.native
5425
  [thread.req.paramname]: #thread.req.paramname
5426
  [thread.req.timing]: #thread.req.timing
5427
+ [thread.sema]: #thread.sema
5428
+ [thread.sema.cnt]: #thread.sema.cnt
5429
  [thread.sharedmutex.class]: #thread.sharedmutex.class
5430
  [thread.sharedmutex.requirements]: #thread.sharedmutex.requirements
5431
  [thread.sharedtimedmutex.class]: #thread.sharedtimedmutex.class
5432
  [thread.sharedtimedmutex.requirements]: #thread.sharedtimedmutex.requirements
5433
+ [thread.stoptoken]: #thread.stoptoken
5434
+ [thread.stoptoken.intro]: #thread.stoptoken.intro
5435
+ [thread.stoptoken.syn]: #thread.stoptoken.syn
5436
+ [thread.summary]: #thread.summary
5437
  [thread.syn]: #thread.syn
5438
  [thread.thread.algorithm]: #thread.thread.algorithm
5439
  [thread.thread.assign]: #thread.thread.assign
5440
  [thread.thread.class]: #thread.thread.class
5441
  [thread.thread.constr]: #thread.thread.constr
 
5446
  [thread.thread.this]: #thread.thread.this
5447
  [thread.threads]: #thread.threads
5448
  [thread.timedmutex.class]: #thread.timedmutex.class
5449
  [thread.timedmutex.recursive]: #thread.timedmutex.recursive
5450
  [thread.timedmutex.requirements]: #thread.timedmutex.requirements
5451
+ [time]: time.md#time
5452
+ [time.clock]: time.md#time.clock
5453
+ [time.clock.req]: time.md#time.clock.req
5454
+ [time.duration]: time.md#time.duration
5455
+ [time.point]: time.md#time.point
5456
  [unord.hash]: utilities.md#unord.hash
5457
 
5458
  [^1]: All implementations for which standard time units are meaningful
5459
  must necessarily have a steady clock within their hardware
5460
  implementation.