From Jason Turner

[thread.condition.condvar]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp9ua8o7rq/{from.md → to.md} +50 -57
tmp/tmp9ua8o7rq/{from.md → to.md} RENAMED
@@ -2,11 +2,10 @@
2
 
3
  ``` cpp
4
  namespace std {
5
  class condition_variable {
6
  public:
7
-
8
  condition_variable();
9
  ~condition_variable();
10
 
11
  condition_variable(const condition_variable&) = delete;
12
  condition_variable& operator=(const condition_variable&) = delete;
@@ -21,60 +20,55 @@ namespace std {
21
  const chrono::time_point<Clock, Duration>& abs_time);
22
  template<class Clock, class Duration, class Predicate>
23
  bool wait_until(unique_lock<mutex>& lock,
24
  const chrono::time_point<Clock, Duration>& abs_time,
25
  Predicate pred);
26
-
27
  template<class Rep, class Period>
28
  cv_status wait_for(unique_lock<mutex>& lock,
29
  const chrono::duration<Rep, Period>& rel_time);
30
  template<class Rep, class Period, class Predicate>
31
  bool wait_for(unique_lock<mutex>& lock,
32
  const chrono::duration<Rep, Period>& rel_time,
33
  Predicate pred);
34
 
35
- using native_handle_type = implementation-defined; // See~[thread.req.native]
36
- native_handle_type native_handle(); // See~[thread.req.native]
37
  };
38
  }
39
  ```
40
 
41
- The class `condition_variable` shall be a standard-layout class (Clause 
42
- [[class]]).
43
 
44
  ``` cpp
45
  condition_variable();
46
  ```
47
 
48
- *Effects:* Constructs an object of type `condition_variable`.
49
-
50
  *Throws:* `system_error` when an exception is
51
- required ([[thread.req.exception]]).
52
 
53
  *Error conditions:*
54
 
55
  - `resource_unavailable_try_again` — if some non-memory resource
56
  limitation prevents initialization.
57
 
58
  ``` cpp
59
  ~condition_variable();
60
  ```
61
 
62
- *Requires:* There shall be no thread blocked on `*this`.
63
 
64
- [*Note 1*: That is, all threads shall have been notified; they may
65
  subsequently block on the lock specified in the wait. This relaxes the
66
  usual rules, which would have required all wait calls to happen before
67
- destruction. Only the notification to unblock the wait must happen
68
- before destruction. The user must take care to ensure that no threads
69
  wait on `*this` once the destructor has been started, especially when
70
  the waiting threads are calling the wait functions in a loop or using
71
  the overloads of `wait`, `wait_for`, or `wait_until` that take a
72
  predicate. — *end note*]
73
 
74
- *Effects:* Destroys the object.
75
-
76
  ``` cpp
77
  void notify_one() noexcept;
78
  ```
79
 
80
  *Effects:* If any threads are blocked waiting for `*this`, unblocks one
@@ -88,12 +82,12 @@ void notify_all() noexcept;
88
 
89
  ``` cpp
90
  void wait(unique_lock<mutex>& lock);
91
  ```
92
 
93
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
94
- the calling thread, and either
95
 
96
  - no other thread is waiting on this `condition_variable` object or
97
  - `lock.mutex()` returns the same value for each of the `lock` arguments
98
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
99
  `wait_until`) threads.
@@ -105,27 +99,27 @@ the calling thread, and either
105
  then returns.
106
  - The function will unblock when signaled by a call to `notify_one()` or
107
  a call to `notify_all()`, or spuriously.
108
 
109
  *Remarks:* If the function fails to meet the postcondition,
110
- `terminate()` shall be called ([[except.terminate]]).
111
 
112
  [*Note 2*: This can happen if the re-locking of the mutex throws an
113
  exception. — *end note*]
114
 
115
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
116
- locked by the calling thread.
117
 
118
  *Throws:* Nothing.
119
 
120
  ``` cpp
121
  template<class Predicate>
122
  void wait(unique_lock<mutex>& lock, Predicate pred);
123
  ```
124
 
125
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
126
- the calling thread, and either
127
 
128
  - no other thread is waiting on this `condition_variable` object or
129
  - `lock.mutex()` returns the same value for each of the `lock` arguments
130
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
131
  `wait_until`) threads.
@@ -136,28 +130,28 @@ the calling thread, and either
136
  while (!pred())
137
  wait(lock);
138
  ```
139
 
140
  *Remarks:* If the function fails to meet the postcondition,
141
- `terminate()` shall be called ([[except.terminate]]).
142
 
143
  [*Note 3*: This can happen if the re-locking of the mutex throws an
144
  exception. — *end note*]
145
 
146
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
147
- locked by the calling thread.
148
 
149
  *Throws:* Any exception thrown by `pred`.
150
 
151
  ``` cpp
152
  template<class Clock, class Duration>
153
  cv_status wait_until(unique_lock<mutex>& lock,
154
  const chrono::time_point<Clock, Duration>& abs_time);
155
  ```
156
 
157
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
158
- the calling thread, and either
159
 
160
  - no other thread is waiting on this `condition_variable` object or
161
  - `lock.mutex()` returns the same value for each of the `lock` arguments
162
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
163
  `wait_until`) threads.
@@ -167,38 +161,37 @@ the calling thread, and either
167
  - Atomically calls `lock.unlock()` and blocks on `*this`.
168
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock),
169
  then returns.
170
  - The function will unblock when signaled by a call to `notify_one()`, a
171
  call to `notify_all()`, expiration of the absolute
172
- timeout ([[thread.req.timing]]) specified by `abs_time`, or
173
- spuriously.
174
- - If the function exits via an exception, `lock.lock()` shall be called
175
- prior to exiting the function.
176
 
177
  *Remarks:* If the function fails to meet the postcondition,
178
- `terminate()` shall be called ([[except.terminate]]).
179
 
180
  [*Note 4*: This can happen if the re-locking of the mutex throws an
181
  exception. — *end note*]
182
 
183
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
184
- locked by the calling thread.
185
 
186
  *Returns:* `cv_status::timeout` if the absolute
187
- timeout ([[thread.req.timing]]) specified by `abs_time` expired,
188
- otherwise `cv_status::no_timeout`.
189
 
190
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
191
 
192
  ``` cpp
193
  template<class Rep, class Period>
194
  cv_status wait_for(unique_lock<mutex>& lock,
195
  const chrono::duration<Rep, Period>& rel_time);
196
  ```
197
 
198
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
199
- the calling thread, and either
200
 
201
  - no other thread is waiting on this `condition_variable` object or
202
  - `lock.mutex()` returns the same value for each of the `lock` arguments
203
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
204
  `wait_until`) threads.
@@ -208,33 +201,33 @@ the calling thread, and either
208
  ``` cpp
209
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
210
  ```
211
 
212
  *Returns:* `cv_status::timeout` if the relative
213
- timeout ([[thread.req.timing]]) specified by `rel_time` expired,
214
- otherwise `cv_status::no_timeout`.
215
 
216
  *Remarks:* If the function fails to meet the postcondition,
217
- `terminate()` shall be called ([[except.terminate]]).
218
 
219
  [*Note 5*: This can happen if the re-locking of the mutex throws an
220
  exception. — *end note*]
221
 
222
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
223
- locked by the calling thread.
224
 
225
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]).
226
 
227
  ``` cpp
228
  template<class Clock, class Duration, class Predicate>
229
  bool wait_until(unique_lock<mutex>& lock,
230
  const chrono::time_point<Clock, Duration>& abs_time,
231
  Predicate pred);
232
  ```
233
 
234
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
235
- the calling thread, and either
236
 
237
  - no other thread is waiting on this `condition_variable` object or
238
  - `lock.mutex()` returns the same value for each of the `lock` arguments
239
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
240
  `wait_until`) threads.
@@ -247,34 +240,34 @@ while (!pred())
247
  return pred();
248
  return true;
249
  ```
250
 
251
  *Remarks:* If the function fails to meet the postcondition,
252
- `terminate()` shall be called ([[except.terminate]]).
253
 
254
  [*Note 6*: This can happen if the re-locking of the mutex throws an
255
  exception. — *end note*]
256
 
257
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
258
- locked by the calling thread.
259
 
260
  [*Note 7*: The returned value indicates whether the predicate evaluated
261
  to `true` regardless of whether the timeout was
262
  triggered. — *end note*]
263
 
264
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]) or any
265
  exception thrown by `pred`.
266
 
267
  ``` cpp
268
  template<class Rep, class Period, class Predicate>
269
  bool wait_for(unique_lock<mutex>& lock,
270
  const chrono::duration<Rep, Period>& rel_time,
271
  Predicate pred);
272
  ```
273
 
274
- *Requires:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
275
- the calling thread, and either
276
 
277
  - no other thread is waiting on this `condition_variable` object or
278
  - `lock.mutex()` returns the same value for each of the `lock` arguments
279
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
280
  `wait_until`) threads.
@@ -287,20 +280,20 @@ return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred))
287
 
288
  [*Note 8*: There is no blocking if `pred()` is initially `true`, even
289
  if the timeout has already expired. — *end note*]
290
 
291
  *Remarks:* If the function fails to meet the postcondition,
292
- `terminate()` shall be called ([[except.terminate]]).
293
 
294
  [*Note 9*: This can happen if the re-locking of the mutex throws an
295
  exception. — *end note*]
296
 
297
- *Postconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
298
- locked by the calling thread.
299
 
300
  [*Note 10*: The returned value indicates whether the predicate
301
  evaluates to `true` regardless of whether the timeout was
302
  triggered. — *end note*]
303
 
304
- *Throws:* Timeout-related exceptions ([[thread.req.timing]]) or any
305
  exception thrown by `pred`.
306
 
 
2
 
3
  ``` cpp
4
  namespace std {
5
  class condition_variable {
6
  public:
 
7
  condition_variable();
8
  ~condition_variable();
9
 
10
  condition_variable(const condition_variable&) = delete;
11
  condition_variable& operator=(const condition_variable&) = delete;
 
20
  const chrono::time_point<Clock, Duration>& abs_time);
21
  template<class Clock, class Duration, class Predicate>
22
  bool wait_until(unique_lock<mutex>& lock,
23
  const chrono::time_point<Clock, Duration>& abs_time,
24
  Predicate pred);
 
25
  template<class Rep, class Period>
26
  cv_status wait_for(unique_lock<mutex>& lock,
27
  const chrono::duration<Rep, Period>& rel_time);
28
  template<class Rep, class Period, class Predicate>
29
  bool wait_for(unique_lock<mutex>& lock,
30
  const chrono::duration<Rep, Period>& rel_time,
31
  Predicate pred);
32
 
33
+ using native_handle_type = implementation-defined; // see~[thread.req.native]
34
+ native_handle_type native_handle(); // see~[thread.req.native]
35
  };
36
  }
37
  ```
38
 
39
+ The class `condition_variable` is a standard-layout class
40
+ [[class.prop]].
41
 
42
  ``` cpp
43
  condition_variable();
44
  ```
45
 
 
 
46
  *Throws:* `system_error` when an exception is
47
+ required [[thread.req.exception]].
48
 
49
  *Error conditions:*
50
 
51
  - `resource_unavailable_try_again` — if some non-memory resource
52
  limitation prevents initialization.
53
 
54
  ``` cpp
55
  ~condition_variable();
56
  ```
57
 
58
+ *Preconditions:* There is no thread blocked on `*this`.
59
 
60
+ [*Note 1*: That is, all threads have been notified; they could
61
  subsequently block on the lock specified in the wait. This relaxes the
62
  usual rules, which would have required all wait calls to happen before
63
+ destruction. Only the notification to unblock the wait needs to happen
64
+ before destruction. The user should take care to ensure that no threads
65
  wait on `*this` once the destructor has been started, especially when
66
  the waiting threads are calling the wait functions in a loop or using
67
  the overloads of `wait`, `wait_for`, or `wait_until` that take a
68
  predicate. — *end note*]
69
 
 
 
70
  ``` cpp
71
  void notify_one() noexcept;
72
  ```
73
 
74
  *Effects:* If any threads are blocked waiting for `*this`, unblocks one
 
82
 
83
  ``` cpp
84
  void wait(unique_lock<mutex>& lock);
85
  ```
86
 
87
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
88
+ locked by the calling thread, and either
89
 
90
  - no other thread is waiting on this `condition_variable` object or
91
  - `lock.mutex()` returns the same value for each of the `lock` arguments
92
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
93
  `wait_until`) threads.
 
99
  then returns.
100
  - The function will unblock when signaled by a call to `notify_one()` or
101
  a call to `notify_all()`, or spuriously.
102
 
103
  *Remarks:* If the function fails to meet the postcondition,
104
+ `terminate()` is called [[except.terminate]].
105
 
106
  [*Note 2*: This can happen if the re-locking of the mutex throws an
107
  exception. — *end note*]
108
 
109
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
110
+ the calling thread.
111
 
112
  *Throws:* Nothing.
113
 
114
  ``` cpp
115
  template<class Predicate>
116
  void wait(unique_lock<mutex>& lock, Predicate pred);
117
  ```
118
 
119
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
120
+ locked by the calling thread, and either
121
 
122
  - no other thread is waiting on this `condition_variable` object or
123
  - `lock.mutex()` returns the same value for each of the `lock` arguments
124
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
125
  `wait_until`) threads.
 
130
  while (!pred())
131
  wait(lock);
132
  ```
133
 
134
  *Remarks:* If the function fails to meet the postcondition,
135
+ `terminate()` is called [[except.terminate]].
136
 
137
  [*Note 3*: This can happen if the re-locking of the mutex throws an
138
  exception. — *end note*]
139
 
140
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
141
+ the calling thread.
142
 
143
  *Throws:* Any exception thrown by `pred`.
144
 
145
  ``` cpp
146
  template<class Clock, class Duration>
147
  cv_status wait_until(unique_lock<mutex>& lock,
148
  const chrono::time_point<Clock, Duration>& abs_time);
149
  ```
150
 
151
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
152
+ locked by the calling thread, and either
153
 
154
  - no other thread is waiting on this `condition_variable` object or
155
  - `lock.mutex()` returns the same value for each of the `lock` arguments
156
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
157
  `wait_until`) threads.
 
161
  - Atomically calls `lock.unlock()` and blocks on `*this`.
162
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock),
163
  then returns.
164
  - The function will unblock when signaled by a call to `notify_one()`, a
165
  call to `notify_all()`, expiration of the absolute
166
+ timeout [[thread.req.timing]] specified by `abs_time`, or spuriously.
167
+ - If the function exits via an exception, `lock.lock()` is called prior
168
+ to exiting the function.
 
169
 
170
  *Remarks:* If the function fails to meet the postcondition,
171
+ `terminate()` is called [[except.terminate]].
172
 
173
  [*Note 4*: This can happen if the re-locking of the mutex throws an
174
  exception. — *end note*]
175
 
176
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
177
+ the calling thread.
178
 
179
  *Returns:* `cv_status::timeout` if the absolute
180
+ timeout [[thread.req.timing]] specified by `abs_time` expired, otherwise
181
+ `cv_status::no_timeout`.
182
 
183
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
184
 
185
  ``` cpp
186
  template<class Rep, class Period>
187
  cv_status wait_for(unique_lock<mutex>& lock,
188
  const chrono::duration<Rep, Period>& rel_time);
189
  ```
190
 
191
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
192
+ locked by the calling thread, and either
193
 
194
  - no other thread is waiting on this `condition_variable` object or
195
  - `lock.mutex()` returns the same value for each of the `lock` arguments
196
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
197
  `wait_until`) threads.
 
201
  ``` cpp
202
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
203
  ```
204
 
205
  *Returns:* `cv_status::timeout` if the relative
206
+ timeout [[thread.req.timing]] specified by `rel_time` expired, otherwise
207
+ `cv_status::no_timeout`.
208
 
209
  *Remarks:* If the function fails to meet the postcondition,
210
+ `terminate()` is called [[except.terminate]].
211
 
212
  [*Note 5*: This can happen if the re-locking of the mutex throws an
213
  exception. — *end note*]
214
 
215
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
216
+ the calling thread.
217
 
218
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
219
 
220
  ``` cpp
221
  template<class Clock, class Duration, class Predicate>
222
  bool wait_until(unique_lock<mutex>& lock,
223
  const chrono::time_point<Clock, Duration>& abs_time,
224
  Predicate pred);
225
  ```
226
 
227
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
228
+ locked by the calling thread, and either
229
 
230
  - no other thread is waiting on this `condition_variable` object or
231
  - `lock.mutex()` returns the same value for each of the `lock` arguments
232
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
233
  `wait_until`) threads.
 
240
  return pred();
241
  return true;
242
  ```
243
 
244
  *Remarks:* If the function fails to meet the postcondition,
245
+ `terminate()` is called [[except.terminate]].
246
 
247
  [*Note 6*: This can happen if the re-locking of the mutex throws an
248
  exception. — *end note*]
249
 
250
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
251
+ the calling thread.
252
 
253
  [*Note 7*: The returned value indicates whether the predicate evaluated
254
  to `true` regardless of whether the timeout was
255
  triggered. — *end note*]
256
 
257
+ *Throws:* Timeout-related exceptions [[thread.req.timing]] or any
258
  exception thrown by `pred`.
259
 
260
  ``` cpp
261
  template<class Rep, class Period, class Predicate>
262
  bool wait_for(unique_lock<mutex>& lock,
263
  const chrono::duration<Rep, Period>& rel_time,
264
  Predicate pred);
265
  ```
266
 
267
+ *Preconditions:* `lock.owns_lock()` is `true` and `lock.mutex()` is
268
+ locked by the calling thread, and either
269
 
270
  - no other thread is waiting on this `condition_variable` object or
271
  - `lock.mutex()` returns the same value for each of the `lock` arguments
272
  supplied by all concurrently waiting (via `wait`, `wait_for`, or
273
  `wait_until`) threads.
 
280
 
281
  [*Note 8*: There is no blocking if `pred()` is initially `true`, even
282
  if the timeout has already expired. — *end note*]
283
 
284
  *Remarks:* If the function fails to meet the postcondition,
285
+ `terminate()` is called [[except.terminate]].
286
 
287
  [*Note 9*: This can happen if the re-locking of the mutex throws an
288
  exception. — *end note*]
289
 
290
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
291
+ the calling thread.
292
 
293
  [*Note 10*: The returned value indicates whether the predicate
294
  evaluates to `true` regardless of whether the timeout was
295
  triggered. — *end note*]
296
 
297
+ *Throws:* Timeout-related exceptions [[thread.req.timing]] or any
298
  exception thrown by `pred`.
299