From Jason Turner

[thread.condition.condvarany]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp96dbl619/{from.md → to.md} +46 -43
tmp/tmp96dbl619/{from.md → to.md} RENAMED
@@ -1,16 +1,19 @@
1
  ### Class `condition_variable_any` <a id="thread.condition.condvarany">[[thread.condition.condvarany]]</a>
2
 
3
- A `Lock` type shall meet the *Cpp17BasicLockable* requirements
4
- [[thread.req.lockable.basic]].
 
 
 
5
 
6
  [*Note 1*: All of the standard mutex types meet this requirement. If a
7
- `Lock` type other than one of the standard mutex types or a
8
- `unique_lock` wrapper for a standard mutex type is used with
9
- `condition_variable_any`, the user should ensure that any necessary
10
- synchronization is in place with respect to the predicate associated
11
- with the `condition_variable_any` instance. — *end note*]
12
 
13
  ``` cpp
14
  namespace std {
15
  class condition_variable_any {
16
  public:
@@ -70,18 +73,18 @@ required [[thread.req.exception]].
70
  ~condition_variable_any();
71
  ```
72
 
73
  *Preconditions:* There is no thread blocked on `*this`.
74
 
75
- [*Note 1*: That is, all threads have been notified; they could
76
  subsequently block on the lock specified in the wait. This relaxes the
77
  usual rules, which would have required all wait calls to happen before
78
  destruction. Only the notification to unblock the wait needs to happen
79
- before destruction. The user should take care to ensure that no threads
80
- wait on `*this` once the destructor has been started, especially when
81
- the waiting threads are calling the wait functions in a loop or using
82
- the overloads of `wait`, `wait_for`, or `wait_until` that take a
83
  predicate. — *end note*]
84
 
85
  ``` cpp
86
  void notify_one() noexcept;
87
  ```
@@ -108,20 +111,20 @@ template<class Lock>
108
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock)
109
  and returns.
110
  - The function will unblock when signaled by a call to `notify_one()`, a
111
  call to `notify_all()`, or spuriously.
112
 
113
- *Remarks:* If the function fails to meet the postcondition,
114
- `terminate()` is called [[except.terminate]].
115
-
116
- [*Note 1*: This can happen if the re-locking of the mutex throws an
117
- exception. — *end note*]
118
-
119
  *Ensures:* `lock` is locked by the calling thread.
120
 
121
  *Throws:* Nothing.
122
 
 
 
 
 
 
 
123
  ``` cpp
124
  template<class Lock, class Predicate>
125
  void wait(Lock& lock, Predicate pred);
126
  ```
127
 
@@ -146,24 +149,24 @@ template<class Lock, class Clock, class Duration>
146
  call to `notify_all()`, expiration of the absolute
147
  timeout [[thread.req.timing]] specified by `abs_time`, or spuriously.
148
  - If the function exits via an exception, `lock.lock()` is called prior
149
  to exiting the function.
150
 
151
- *Remarks:* If the function fails to meet the postcondition,
152
- `terminate()` is called [[except.terminate]].
153
-
154
- [*Note 2*: This can happen if the re-locking of the mutex throws an
155
- exception. — *end note*]
156
-
157
  *Ensures:* `lock` is locked by the calling thread.
158
 
159
  *Returns:* `cv_status::timeout` if the absolute
160
  timeout [[thread.req.timing]] specified by `abs_time` expired, otherwise
161
  `cv_status::no_timeout`.
162
 
163
  *Throws:* Timeout-related exceptions [[thread.req.timing]].
164
 
 
 
 
 
 
 
165
  ``` cpp
166
  template<class Lock, class Rep, class Period>
167
  cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
168
  ```
169
 
@@ -171,24 +174,24 @@ template<class Lock, class Rep, class Period>
171
 
172
  ``` cpp
173
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
174
  ```
175
 
 
 
176
  *Returns:* `cv_status::timeout` if the relative
177
  timeout [[thread.req.timing]] specified by `rel_time` expired, otherwise
178
  `cv_status::no_timeout`.
179
 
180
- *Remarks:* If the function fails to meet the postcondition,
181
- `terminate()` is called [[except.terminate]].
 
 
182
 
183
  [*Note 3*: This can happen if the re-locking of the mutex throws an
184
  exception. — *end note*]
185
 
186
- *Ensures:* `lock` is locked by the calling thread.
187
-
188
- *Throws:* Timeout-related exceptions [[thread.req.timing]].
189
-
190
  ``` cpp
191
  template<class Lock, class Clock, class Duration, class Predicate>
192
  bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
193
  ```
194
 
@@ -246,18 +249,18 @@ return pred();
246
  [*Note 1*: The returned value indicates whether the predicate evaluated
247
  to `true` regardless of whether there was a stop request. — *end note*]
248
 
249
  *Ensures:* `lock` is locked by the calling thread.
250
 
251
- *Remarks:* If the function fails to meet the postcondition, `terminate`
252
- is called [[except.terminate]].
253
-
254
- [*Note 2*: This can happen if the re-locking of the mutex throws an
255
- exception. — *end note*]
256
-
257
  *Throws:* Any exception thrown by `pred`.
258
 
 
 
 
 
 
 
259
  ``` cpp
260
  template<class Lock, class Clock, class Duration, class Predicate>
261
  bool wait_until(Lock& lock, stop_token stoken,
262
  const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
263
  ```
@@ -268,11 +271,11 @@ equivalent to:
268
 
269
  ``` cpp
270
  while (!stoken.stop_requested()) {
271
  if (pred())
272
  return true;
273
- if (cv.wait_until(lock, abs_time) == cv_status::timeout)
274
  return pred();
275
  }
276
  return pred();
277
  ```
278
 
@@ -284,19 +287,19 @@ expired. — *end note*]
284
  to `true` regardless of whether the timeout was triggered or a stop
285
  request was made. — *end note*]
286
 
287
  *Ensures:* `lock` is locked by the calling thread.
288
 
289
- *Remarks:* If the function fails to meet the postcondition, `terminate`
290
- is called [[except.terminate]].
291
-
292
- [*Note 5*: This can happen if the re-locking of the mutex throws an
293
- exception. — *end note*]
294
-
295
  *Throws:* Timeout-related exceptions [[thread.req.timing]], or any
296
  exception thrown by `pred`.
297
 
 
 
 
 
 
 
298
  ``` cpp
299
  template<class Lock, class Rep, class Period, class Predicate>
300
  bool wait_for(Lock& lock, stop_token stoken,
301
  const chrono::duration<Rep, Period>& rel_time, Predicate pred);
302
  ```
 
1
  ### Class `condition_variable_any` <a id="thread.condition.condvarany">[[thread.condition.condvarany]]</a>
2
 
3
+ #### General <a id="thread.condition.condvarany.general">[[thread.condition.condvarany.general]]</a>
4
+
5
+ In this subclause [[thread.condition.condvarany]], template arguments
6
+ for template parameters named `Lock` shall meet the *Cpp17BasicLockable*
7
+ requirements [[thread.req.lockable.basic]].
8
 
9
  [*Note 1*: All of the standard mutex types meet this requirement. If a
10
+ type other than one of the standard mutex types or a `unique_lock`
11
+ wrapper for a standard mutex type is used with `condition_variable_any`,
12
+ any necessary synchronization is assumed to be in place with respect to
13
+ the predicate associated with the `condition_variable_any`
14
+ instance. — *end note*]
15
 
16
  ``` cpp
17
  namespace std {
18
  class condition_variable_any {
19
  public:
 
73
  ~condition_variable_any();
74
  ```
75
 
76
  *Preconditions:* There is no thread blocked on `*this`.
77
 
78
+ [*Note 1*: That is, all threads have been notified; they can
79
  subsequently block on the lock specified in the wait. This relaxes the
80
  usual rules, which would have required all wait calls to happen before
81
  destruction. Only the notification to unblock the wait needs to happen
82
+ before destruction. Undefined behavior ensues if a thread waits on
83
+ `*this` once the destructor has been started, especially when the
84
+ waiting threads are calling the wait functions in a loop or using the
85
+ overloads of `wait`, `wait_for`, or `wait_until` that take a
86
  predicate. — *end note*]
87
 
88
  ``` cpp
89
  void notify_one() noexcept;
90
  ```
 
111
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock)
112
  and returns.
113
  - The function will unblock when signaled by a call to `notify_one()`, a
114
  call to `notify_all()`, or spuriously.
115
 
 
 
 
 
 
 
116
  *Ensures:* `lock` is locked by the calling thread.
117
 
118
  *Throws:* Nothing.
119
 
120
+ *Remarks:* If the function fails to meet the postcondition,
121
+ `terminate()` is invoked [[except.terminate]].
122
+
123
+ [*Note 1*: This can happen if the re-locking of the mutex throws an
124
+ exception. — *end note*]
125
+
126
  ``` cpp
127
  template<class Lock, class Predicate>
128
  void wait(Lock& lock, Predicate pred);
129
  ```
130
 
 
149
  call to `notify_all()`, expiration of the absolute
150
  timeout [[thread.req.timing]] specified by `abs_time`, or spuriously.
151
  - If the function exits via an exception, `lock.lock()` is called prior
152
  to exiting the function.
153
 
 
 
 
 
 
 
154
  *Ensures:* `lock` is locked by the calling thread.
155
 
156
  *Returns:* `cv_status::timeout` if the absolute
157
  timeout [[thread.req.timing]] specified by `abs_time` expired, otherwise
158
  `cv_status::no_timeout`.
159
 
160
  *Throws:* Timeout-related exceptions [[thread.req.timing]].
161
 
162
+ *Remarks:* If the function fails to meet the postcondition,
163
+ `terminate()` is invoked [[except.terminate]].
164
+
165
+ [*Note 2*: This can happen if the re-locking of the mutex throws an
166
+ exception. — *end note*]
167
+
168
  ``` cpp
169
  template<class Lock, class Rep, class Period>
170
  cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
171
  ```
172
 
 
174
 
175
  ``` cpp
176
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
177
  ```
178
 
179
+ *Ensures:* `lock` is locked by the calling thread.
180
+
181
  *Returns:* `cv_status::timeout` if the relative
182
  timeout [[thread.req.timing]] specified by `rel_time` expired, otherwise
183
  `cv_status::no_timeout`.
184
 
185
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
186
+
187
+ *Remarks:* If the function fails to meet the postcondition, `terminate`
188
+ is invoked [[except.terminate]].
189
 
190
  [*Note 3*: This can happen if the re-locking of the mutex throws an
191
  exception. — *end note*]
192
 
 
 
 
 
193
  ``` cpp
194
  template<class Lock, class Clock, class Duration, class Predicate>
195
  bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
196
  ```
197
 
 
249
  [*Note 1*: The returned value indicates whether the predicate evaluated
250
  to `true` regardless of whether there was a stop request. — *end note*]
251
 
252
  *Ensures:* `lock` is locked by the calling thread.
253
 
 
 
 
 
 
 
254
  *Throws:* Any exception thrown by `pred`.
255
 
256
+ *Remarks:* If the function fails to meet the postcondition, `terminate`
257
+ is called [[except.terminate]].
258
+
259
+ [*Note 2*: This can happen if the re-locking of the mutex throws an
260
+ exception. — *end note*]
261
+
262
  ``` cpp
263
  template<class Lock, class Clock, class Duration, class Predicate>
264
  bool wait_until(Lock& lock, stop_token stoken,
265
  const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
266
  ```
 
271
 
272
  ``` cpp
273
  while (!stoken.stop_requested()) {
274
  if (pred())
275
  return true;
276
+ if (wait_until(lock, abs_time) == cv_status::timeout)
277
  return pred();
278
  }
279
  return pred();
280
  ```
281
 
 
287
  to `true` regardless of whether the timeout was triggered or a stop
288
  request was made. — *end note*]
289
 
290
  *Ensures:* `lock` is locked by the calling thread.
291
 
 
 
 
 
 
 
292
  *Throws:* Timeout-related exceptions [[thread.req.timing]], or any
293
  exception thrown by `pred`.
294
 
295
+ *Remarks:* If the function fails to meet the postcondition, `terminate`
296
+ is called [[except.terminate]].
297
+
298
+ [*Note 5*: This can happen if the re-locking of the mutex throws an
299
+ exception. — *end note*]
300
+
301
  ``` cpp
302
  template<class Lock, class Rep, class Period, class Predicate>
303
  bool wait_for(Lock& lock, stop_token stoken,
304
  const chrono::duration<Rep, Period>& rel_time, Predicate pred);
305
  ```