From Jason Turner

[thread.lock.unique]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpvscylud4/{from.md → to.md} +82 -71
tmp/tmpvscylud4/{from.md → to.md} RENAMED
@@ -3,13 +3,13 @@
3
  ``` cpp
4
  namespace std {
5
  template <class Mutex>
6
  class unique_lock {
7
  public:
8
- typedef Mutex mutex_type;
9
 
10
- // [thread.lock.unique.cons], construct/copy/destroy:
11
  unique_lock() noexcept;
12
  explicit unique_lock(mutex_type& m);
13
  unique_lock(mutex_type& m, defer_lock_t) noexcept;
14
  unique_lock(mutex_type& m, try_to_lock_t);
15
  unique_lock(mutex_type& m, adopt_lock_t);
@@ -17,41 +17,43 @@ namespace std {
17
  unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
18
  template <class Rep, class Period>
19
  unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
20
  ~unique_lock();
21
 
22
- unique_lock(unique_lock const&) = delete;
23
- unique_lock& operator=(unique_lock const&) = delete;
24
 
25
  unique_lock(unique_lock&& u) noexcept;
26
  unique_lock& operator=(unique_lock&& u);
27
 
28
- // [thread.lock.unique.locking], locking:
29
  void lock();
30
  bool try_lock();
31
 
32
  template <class Rep, class Period>
33
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
34
  template <class Clock, class Duration>
35
  bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
36
 
37
  void unlock();
38
 
39
- // [thread.lock.unique.mod], modifiers:
40
  void swap(unique_lock& u) noexcept;
41
  mutex_type* release() noexcept;
42
 
43
- // [thread.lock.unique.obs], observers:
44
  bool owns_lock() const noexcept;
45
  explicit operator bool () const noexcept;
46
  mutex_type* mutex() const noexcept;
47
 
48
  private:
49
  mutex_type* pm; // exposition only
50
  bool owns; // exposition only
51
  };
52
 
 
 
53
  template <class Mutex>
54
  void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
55
  }
56
  ```
57
 
@@ -64,15 +66,16 @@ program is undefined if the contained pointer `pm` is not null and the
64
  lockable object pointed to by `pm` does not exist for the entire
65
  remaining lifetime ([[basic.life]]) of the `unique_lock` object. The
66
  supplied `Mutex` type shall meet the `BasicLockable` requirements (
67
  [[thread.req.lockable.basic]]).
68
 
69
- `unique_lock<Mutex>` meets the `BasicLockable` requirements. If `Mutex`
70
- meets the `Lockable` requirements ([[thread.req.lockable.req]]),
71
- `unique_lock<Mutex>` also meets the `Lockable` requirements; if `Mutex`
72
- meets the `TimedLockable` requirements ([[thread.req.lockable.timed]]),
73
- `unique_lock<Mutex>` also meets the `TimedLockable` requirements.
 
74
 
75
  ##### `unique_lock` constructors, destructor, and assignment <a id="thread.lock.unique.cons">[[thread.lock.unique.cons]]</a>
76
 
77
  ``` cpp
78
  unique_lock() noexcept;
@@ -84,81 +87,81 @@ unique_lock() noexcept;
84
 
85
  ``` cpp
86
  explicit unique_lock(mutex_type& m);
87
  ```
88
 
89
- If `mutex_type` is not a recursive mutex the calling thread does not own
90
- the mutex.
91
 
92
  *Effects:* Constructs an object of type `unique_lock` and calls
93
  `m.lock()`.
94
 
95
- *Postconditions:* `pm == &m` and `owns == true`.
96
 
97
  ``` cpp
98
  unique_lock(mutex_type& m, defer_lock_t) noexcept;
99
  ```
100
 
101
  *Effects:* Constructs an object of type `unique_lock`.
102
 
103
- *Postconditions:* `pm == &m` and `owns == false`.
104
 
105
  ``` cpp
106
  unique_lock(mutex_type& m, try_to_lock_t);
107
  ```
108
 
109
- The supplied `Mutex` type shall meet the `Lockable`
110
  requirements ([[thread.req.lockable.req]]). If `mutex_type` is not a
111
  recursive mutex the calling thread does not own the mutex.
112
 
113
  *Effects:* Constructs an object of type `unique_lock` and calls
114
  `m.try_lock()`.
115
 
116
- *Postconditions:* `pm == &m` and `owns == res`, where `res` is the value
117
- returned by the call to `m.try_lock()`.
118
 
119
  ``` cpp
120
  unique_lock(mutex_type& m, adopt_lock_t);
121
  ```
122
 
123
- The calling thread own the mutex.
124
 
125
  *Effects:* Constructs an object of type `unique_lock`.
126
 
127
- *Postconditions:* `pm == &m` and `owns == true`.
128
 
129
  *Throws:* Nothing.
130
 
131
  ``` cpp
132
  template <class Clock, class Duration>
133
  unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
134
  ```
135
 
136
- If `mutex_type` is not a recursive mutex the calling thread does not own
137
- the mutex. The supplied `Mutex` type shall meet the `TimedLockable`
138
- requirements ([[thread.req.lockable.timed]]).
139
 
140
  *Effects:* Constructs an object of type `unique_lock` and calls
141
  `m.try_lock_until(abs_time)`.
142
 
143
- *Postconditions:* `pm == &m` and `owns == res`, where `res` is the value
144
- returned by the call to `m.try_lock_until(abs_time)`.
145
 
146
  ``` cpp
147
  template <class Rep, class Period>
148
  unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
149
  ```
150
 
151
- If `mutex_type` is not a recursive mutex the calling thread does not own
152
- the mutex. The supplied `Mutex` type shall meet the `TimedLockable`
153
- requirements ([[thread.req.lockable.timed]]).
154
 
155
  *Effects:* Constructs an object of type `unique_lock` and calls
156
  `m.try_lock_for(rel_time)`.
157
 
158
- *Postconditions:* `pm == &m` and `owns == res`, where `res` is the value
159
- returned by the call to `m.try_lock_for(rel_time)`.
160
 
161
  ``` cpp
162
  unique_lock(unique_lock&& u) noexcept;
163
  ```
164
 
@@ -174,13 +177,13 @@ unique_lock& operator=(unique_lock&& u);
174
 
175
  *Postconditions:* `pm == u_p.pm` and `owns == u_p.owns` (where `u_p` is
176
  the state of `u` just prior to this construction), `u.pm == 0` and
177
  `u.owns == false`.
178
 
179
- With a recursive mutex it is possible for both `*this` and `u` to own
180
- the same mutex before the assignment. In this case, `*this` will own the
181
- mutex after the assignment and `u` will not.
182
 
183
  *Throws:* Nothing.
184
 
185
  ``` cpp
186
  ~unique_lock();
@@ -192,96 +195,104 @@ mutex after the assignment and `u` will not.
192
 
193
  ``` cpp
194
  void lock();
195
  ```
196
 
197
- *Effects:* `pm->lock()`
198
 
199
- `owns == true`
200
 
201
- *Throws:* Any exception thrown by `pm->lock()`. `system_error` if an
202
- exception is required ([[thread.req.exception]]). `system_error` with
203
- an error condition of `operation_not_permitted` if `pm` is 0.
204
- `system_error` with an error condition of
205
- `resource_deadlock_would_occur` if on entry `owns` is `true`.
 
 
206
 
207
  ``` cpp
208
  bool try_lock();
209
  ```
210
 
211
- The supplied `Mutex` shall meet the `Lockable`
212
  requirements ([[thread.req.lockable.req]]).
213
 
214
- *Effects:* `pm->try_lock()`
215
 
216
  *Returns:* The value returned by the call to `try_lock()`.
217
 
218
- `owns == res`, where `res` is the value returned by the call to
219
- `try_lock()`.
220
 
221
- *Throws:* Any exception thrown by `pm->try_lock()`. `system_error` if an
222
- exception is required ([[thread.req.exception]]). `system_error` with
223
- an error condition of `operation_not_permitted` if `pm` is 0.
224
- `system_error` with an error condition of
225
- `resource_deadlock_would_occur` if on entry `owns` is `true`.
 
 
226
 
227
  ``` cpp
228
  template <class Clock, class Duration>
229
  bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
230
  ```
231
 
232
  *Requires:* The supplied `Mutex` type shall meet the `TimedLockable`
233
  requirements ([[thread.req.lockable.timed]]).
234
 
235
- *Effects:* `pm->try_lock_until(abs_time)`
236
 
237
  *Returns:* The value returned by the call to `try_lock_until(abs_time)`.
238
 
239
- `owns == res`, where `res` is the value returned by the call to
240
- `try_lock_until(abs_time)`.
241
 
242
  *Throws:* Any exception thrown by `pm->try_lock_until()`. `system_error`
243
- if an exception is required ([[thread.req.exception]]). `system_error`
244
- with an error condition of `operation_not_permitted` if `pm` is 0.
245
- `system_error` with an error condition of
246
- `resource_deadlock_would_occur` if on entry `owns` is `true`.
 
 
247
 
248
  ``` cpp
249
  template <class Rep, class Period>
250
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
251
  ```
252
 
253
  *Requires:* The supplied `Mutex` type shall meet the `TimedLockable`
254
  requirements ([[thread.req.lockable.timed]]).
255
 
256
- *Effects:* `pm->try_lock_for(rel_time)`.
257
 
258
  *Returns:* The value returned by the call to `try_lock_until(rel_time)`.
259
 
260
- `owns == res`, where `res` is the value returned by the call to
261
- `try_lock_for(rel_time)`.
262
 
263
  *Throws:* Any exception thrown by `pm->try_lock_for()`. `system_error`
264
- if an exception is required ([[thread.req.exception]]). `system_error`
265
- with an error condition of `operation_not_permitted` if `pm` is 0.
266
- `system_error` with an error condition of
267
- `resource_deadlock_would_occur` if on entry `owns` is `true`.
 
 
268
 
269
  ``` cpp
270
  void unlock();
271
  ```
272
 
273
- *Effects:* `pm->unlock()`
274
 
275
- `owns == false`
276
 
277
  *Throws:* `system_error` when an exception is
278
  required ([[thread.req.exception]]).
279
 
280
  *Error conditions:*
281
 
282
- - `operation_not_permitted` — if on entry `owns` is false.
283
 
284
  ##### `unique_lock` modifiers <a id="thread.lock.unique.mod">[[thread.lock.unique.mod]]</a>
285
 
286
  ``` cpp
287
  void swap(unique_lock& u) noexcept;
@@ -300,27 +311,27 @@ mutex_type* release() noexcept;
300
  ``` cpp
301
  template <class Mutex>
302
  void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
303
  ```
304
 
305
- *Effects:* `x.swap(y)`
306
 
307
  ##### `unique_lock` observers <a id="thread.lock.unique.obs">[[thread.lock.unique.obs]]</a>
308
 
309
  ``` cpp
310
  bool owns_lock() const noexcept;
311
  ```
312
 
313
- *Returns:* `owns`
314
 
315
  ``` cpp
316
  explicit operator bool() const noexcept;
317
  ```
318
 
319
- *Returns:* `owns`
320
 
321
  ``` cpp
322
  mutex_type *mutex() const noexcept;
323
  ```
324
 
325
- *Returns:* `pm`
326
 
 
3
  ``` cpp
4
  namespace std {
5
  template <class Mutex>
6
  class unique_lock {
7
  public:
8
+ using mutex_type = Mutex;
9
 
10
+ // [thread.lock.unique.cons], construct/copy/destroy
11
  unique_lock() noexcept;
12
  explicit unique_lock(mutex_type& m);
13
  unique_lock(mutex_type& m, defer_lock_t) noexcept;
14
  unique_lock(mutex_type& m, try_to_lock_t);
15
  unique_lock(mutex_type& m, adopt_lock_t);
 
17
  unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
18
  template <class Rep, class Period>
19
  unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
20
  ~unique_lock();
21
 
22
+ unique_lock(const unique_lock&) = delete;
23
+ unique_lock& operator=(const unique_lock&) = delete;
24
 
25
  unique_lock(unique_lock&& u) noexcept;
26
  unique_lock& operator=(unique_lock&& u);
27
 
28
+ // [thread.lock.unique.locking], locking
29
  void lock();
30
  bool try_lock();
31
 
32
  template <class Rep, class Period>
33
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
34
  template <class Clock, class Duration>
35
  bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
36
 
37
  void unlock();
38
 
39
+ // [thread.lock.unique.mod], modifiers
40
  void swap(unique_lock& u) noexcept;
41
  mutex_type* release() noexcept;
42
 
43
+ // [thread.lock.unique.obs], observers
44
  bool owns_lock() const noexcept;
45
  explicit operator bool () const noexcept;
46
  mutex_type* mutex() const noexcept;
47
 
48
  private:
49
  mutex_type* pm; // exposition only
50
  bool owns; // exposition only
51
  };
52
 
53
+ template<class Mutex> unique_lock(unique_lock<Mutex>) -> unique_lock<Mutex>;
54
+
55
  template <class Mutex>
56
  void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
57
  }
58
  ```
59
 
 
66
  lockable object pointed to by `pm` does not exist for the entire
67
  remaining lifetime ([[basic.life]]) of the `unique_lock` object. The
68
  supplied `Mutex` type shall meet the `BasicLockable` requirements (
69
  [[thread.req.lockable.basic]]).
70
 
71
+ [*Note 1*: `unique_lock<Mutex>` meets the `BasicLockable` requirements.
72
+ If `Mutex` meets the `Lockable` requirements (
73
+ [[thread.req.lockable.req]]), `unique_lock<Mutex>` also meets the
74
+ `Lockable` requirements; if `Mutex` meets the `TimedLockable`
75
+ requirements ([[thread.req.lockable.timed]]), `unique_lock<Mutex>` also
76
+ meets the `TimedLockable` requirements. — *end note*]
77
 
78
  ##### `unique_lock` constructors, destructor, and assignment <a id="thread.lock.unique.cons">[[thread.lock.unique.cons]]</a>
79
 
80
  ``` cpp
81
  unique_lock() noexcept;
 
87
 
88
  ``` cpp
89
  explicit unique_lock(mutex_type& m);
90
  ```
91
 
92
+ *Requires:* If `mutex_type` is not a recursive mutex the calling thread
93
+ does not own the mutex.
94
 
95
  *Effects:* Constructs an object of type `unique_lock` and calls
96
  `m.lock()`.
97
 
98
+ *Postconditions:* `pm == addressof(m)` and `owns == true`.
99
 
100
  ``` cpp
101
  unique_lock(mutex_type& m, defer_lock_t) noexcept;
102
  ```
103
 
104
  *Effects:* Constructs an object of type `unique_lock`.
105
 
106
+ *Postconditions:* `pm == addressof(m)` and `owns == false`.
107
 
108
  ``` cpp
109
  unique_lock(mutex_type& m, try_to_lock_t);
110
  ```
111
 
112
+ *Requires:* The supplied `Mutex` type shall meet the `Lockable`
113
  requirements ([[thread.req.lockable.req]]). If `mutex_type` is not a
114
  recursive mutex the calling thread does not own the mutex.
115
 
116
  *Effects:* Constructs an object of type `unique_lock` and calls
117
  `m.try_lock()`.
118
 
119
+ *Postconditions:* `pm == addressof(m)` and `owns == res`, where `res` is
120
+ the value returned by the call to `m.try_lock()`.
121
 
122
  ``` cpp
123
  unique_lock(mutex_type& m, adopt_lock_t);
124
  ```
125
 
126
+ *Requires:* The calling thread owns the mutex.
127
 
128
  *Effects:* Constructs an object of type `unique_lock`.
129
 
130
+ *Postconditions:* `pm == addressof(m)` and `owns == true`.
131
 
132
  *Throws:* Nothing.
133
 
134
  ``` cpp
135
  template <class Clock, class Duration>
136
  unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
137
  ```
138
 
139
+ *Requires:* If `mutex_type` is not a recursive mutex the calling thread
140
+ does not own the mutex. The supplied `Mutex` type shall meet the
141
+ `TimedLockable` requirements ([[thread.req.lockable.timed]]).
142
 
143
  *Effects:* Constructs an object of type `unique_lock` and calls
144
  `m.try_lock_until(abs_time)`.
145
 
146
+ *Postconditions:* `pm == addressof(m)` and `owns == res`, where `res` is
147
+ the value returned by the call to `m.try_lock_until(abs_time)`.
148
 
149
  ``` cpp
150
  template <class Rep, class Period>
151
  unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
152
  ```
153
 
154
+ *Requires:* If `mutex_type` is not a recursive mutex the calling thread
155
+ does not own the mutex. The supplied `Mutex` type shall meet the
156
+ `TimedLockable` requirements ([[thread.req.lockable.timed]]).
157
 
158
  *Effects:* Constructs an object of type `unique_lock` and calls
159
  `m.try_lock_for(rel_time)`.
160
 
161
+ *Postconditions:* `pm == addressof(m)` and `owns == res`, where `res` is
162
+ the value returned by the call to `m.try_lock_for(rel_time)`.
163
 
164
  ``` cpp
165
  unique_lock(unique_lock&& u) noexcept;
166
  ```
167
 
 
177
 
178
  *Postconditions:* `pm == u_p.pm` and `owns == u_p.owns` (where `u_p` is
179
  the state of `u` just prior to this construction), `u.pm == 0` and
180
  `u.owns == false`.
181
 
182
+ [*Note 1*: With a recursive mutex it is possible for both `*this` and
183
+ `u` to own the same mutex before the assignment. In this case, `*this`
184
+ will own the mutex after the assignment and `u` will not. — *end note*]
185
 
186
  *Throws:* Nothing.
187
 
188
  ``` cpp
189
  ~unique_lock();
 
195
 
196
  ``` cpp
197
  void lock();
198
  ```
199
 
200
+ *Effects:* As if by `pm->lock()`.
201
 
202
+ *Postconditions:* `owns == true`.
203
 
204
+ *Throws:* Any exception thrown by `pm->lock()`. `system_error` when an
205
+ exception is required ([[thread.req.exception]]).
206
+
207
+ *Error conditions:*
208
+
209
+ - `operation_not_permitted` — if `pm` is `nullptr`.
210
+ - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
211
 
212
  ``` cpp
213
  bool try_lock();
214
  ```
215
 
216
+ *Requires:* The supplied `Mutex` shall meet the `Lockable`
217
  requirements ([[thread.req.lockable.req]]).
218
 
219
+ *Effects:* As if by `pm->try_lock()`.
220
 
221
  *Returns:* The value returned by the call to `try_lock()`.
222
 
223
+ *Postconditions:* `owns == res`, where `res` is the value returned by
224
+ the call to `try_lock()`.
225
 
226
+ *Throws:* Any exception thrown by `pm->try_lock()`. `system_error` when
227
+ an exception is required ([[thread.req.exception]]).
228
+
229
+ *Error conditions:*
230
+
231
+ - `operation_not_permitted` — if `pm` is `nullptr`.
232
+ - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
233
 
234
  ``` cpp
235
  template <class Clock, class Duration>
236
  bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
237
  ```
238
 
239
  *Requires:* The supplied `Mutex` type shall meet the `TimedLockable`
240
  requirements ([[thread.req.lockable.timed]]).
241
 
242
+ *Effects:* As if by `pm->try_lock_until(abs_time)`.
243
 
244
  *Returns:* The value returned by the call to `try_lock_until(abs_time)`.
245
 
246
+ *Postconditions:* `owns == res`, where `res` is the value returned by
247
+ the call to `try_lock_until(abs_time)`.
248
 
249
  *Throws:* Any exception thrown by `pm->try_lock_until()`. `system_error`
250
+ when an exception is required ([[thread.req.exception]]).
251
+
252
+ *Error conditions:*
253
+
254
+ - `operation_not_permitted` — if `pm` is `nullptr`.
255
+ - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
256
 
257
  ``` cpp
258
  template <class Rep, class Period>
259
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
260
  ```
261
 
262
  *Requires:* The supplied `Mutex` type shall meet the `TimedLockable`
263
  requirements ([[thread.req.lockable.timed]]).
264
 
265
+ *Effects:* As if by `pm->try_lock_for(rel_time)`.
266
 
267
  *Returns:* The value returned by the call to `try_lock_until(rel_time)`.
268
 
269
+ *Postconditions:* `owns == res`, where `res` is the value returned by
270
+ the call to `try_lock_for(rel_time)`.
271
 
272
  *Throws:* Any exception thrown by `pm->try_lock_for()`. `system_error`
273
+ when an exception is required ([[thread.req.exception]]).
274
+
275
+ *Error conditions:*
276
+
277
+ - `operation_not_permitted` — if `pm` is `nullptr`.
278
+ - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
279
 
280
  ``` cpp
281
  void unlock();
282
  ```
283
 
284
+ *Effects:* As if by `pm->unlock()`.
285
 
286
+ *Postconditions:* `owns == false`.
287
 
288
  *Throws:* `system_error` when an exception is
289
  required ([[thread.req.exception]]).
290
 
291
  *Error conditions:*
292
 
293
+ - `operation_not_permitted` — if on entry `owns` is `false`.
294
 
295
  ##### `unique_lock` modifiers <a id="thread.lock.unique.mod">[[thread.lock.unique.mod]]</a>
296
 
297
  ``` cpp
298
  void swap(unique_lock& u) noexcept;
 
311
  ``` cpp
312
  template <class Mutex>
313
  void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
314
  ```
315
 
316
+ *Effects:* As if by `x.swap(y)`.
317
 
318
  ##### `unique_lock` observers <a id="thread.lock.unique.obs">[[thread.lock.unique.obs]]</a>
319
 
320
  ``` cpp
321
  bool owns_lock() const noexcept;
322
  ```
323
 
324
+ *Returns:* `owns`.
325
 
326
  ``` cpp
327
  explicit operator bool() const noexcept;
328
  ```
329
 
330
+ *Returns:* `owns`.
331
 
332
  ``` cpp
333
  mutex_type *mutex() const noexcept;
334
  ```
335
 
336
+ *Returns:* `pm`.
337