tmp/tmp72ygan_h/{from.md → to.md}
RENAMED
|
@@ -1,7 +1,9 @@
|
|
| 1 |
### Locks <a id="thread.lock">[[thread.lock]]</a>
|
| 2 |
|
|
|
|
|
|
|
| 3 |
A *lock* is an object that holds a reference to a lockable object and
|
| 4 |
may unlock the lockable object during the lock’s destruction (such as
|
| 5 |
when leaving block scope). An execution agent may use a lock to aid in
|
| 6 |
managing ownership of a lockable object in an exception safe manner. A
|
| 7 |
lock is said to *own* a lockable object if it is currently managing the
|
|
@@ -61,39 +63,36 @@ object referenced by `pm` does not exist for the entire lifetime of the
|
|
| 61 |
|
| 62 |
``` cpp
|
| 63 |
explicit lock_guard(mutex_type& m);
|
| 64 |
```
|
| 65 |
|
| 66 |
-
*Preconditions:* If `mutex_type` is not a recursive mutex, the calling
|
| 67 |
-
thread does not own the mutex `m`.
|
| 68 |
-
|
| 69 |
*Effects:* Initializes `pm` with `m`. Calls `m.lock()`.
|
| 70 |
|
| 71 |
``` cpp
|
| 72 |
lock_guard(mutex_type& m, adopt_lock_t);
|
| 73 |
```
|
| 74 |
|
| 75 |
-
*Preconditions:* The calling thread
|
| 76 |
|
| 77 |
*Effects:* Initializes `pm` with `m`.
|
| 78 |
|
| 79 |
*Throws:* Nothing.
|
| 80 |
|
| 81 |
``` cpp
|
| 82 |
~lock_guard();
|
| 83 |
```
|
| 84 |
|
| 85 |
-
*Effects:*
|
| 86 |
|
| 87 |
#### Class template `scoped_lock` <a id="thread.lock.scoped">[[thread.lock.scoped]]</a>
|
| 88 |
|
| 89 |
``` cpp
|
| 90 |
namespace std {
|
| 91 |
template<class... MutexTypes>
|
| 92 |
class scoped_lock {
|
| 93 |
public:
|
| 94 |
-
using mutex_type =
|
| 95 |
|
| 96 |
explicit scoped_lock(MutexTypes&... m);
|
| 97 |
explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
|
| 98 |
~scoped_lock();
|
| 99 |
|
|
@@ -109,32 +108,35 @@ namespace std {
|
|
| 109 |
An object of type `scoped_lock` controls the ownership of lockable
|
| 110 |
objects within a scope. A `scoped_lock` object maintains ownership of
|
| 111 |
lockable objects throughout the `scoped_lock` object’s lifetime
|
| 112 |
[[basic.life]]. The behavior of a program is undefined if the lockable
|
| 113 |
objects referenced by `pm` do not exist for the entire lifetime of the
|
| 114 |
-
`scoped_lock` object.
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
|
| 119 |
``` cpp
|
| 120 |
explicit scoped_lock(MutexTypes&... m);
|
| 121 |
```
|
| 122 |
|
| 123 |
-
*Preconditions:* If a `MutexTypes` type is not a recursive mutex, the
|
| 124 |
-
calling thread does not own the corresponding mutex element of `m`.
|
| 125 |
-
|
| 126 |
*Effects:* Initializes `pm` with `tie(m...)`. Then if
|
| 127 |
`sizeof...(MutexTypes)` is `0`, no effects. Otherwise if
|
| 128 |
`sizeof...(MutexTypes)` is `1`, then `m.lock()`. Otherwise,
|
| 129 |
`lock(m...)`.
|
| 130 |
|
| 131 |
``` cpp
|
| 132 |
explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
|
| 133 |
```
|
| 134 |
|
| 135 |
-
*Preconditions:* The calling thread
|
|
|
|
| 136 |
|
| 137 |
*Effects:* Initializes `pm` with `tie(m...)`.
|
| 138 |
|
| 139 |
*Throws:* Nothing.
|
| 140 |
|
|
@@ -145,10 +147,12 @@ explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
|
|
| 145 |
*Effects:* For all `i` in \[`0`, `sizeof...(MutexTypes)`),
|
| 146 |
`get<i>(pm).unlock()`.
|
| 147 |
|
| 148 |
#### Class template `unique_lock` <a id="thread.lock.unique">[[thread.lock.unique]]</a>
|
| 149 |
|
|
|
|
|
|
|
| 150 |
``` cpp
|
| 151 |
namespace std {
|
| 152 |
template<class Mutex>
|
| 153 |
class unique_lock {
|
| 154 |
public:
|
|
@@ -194,13 +198,10 @@ namespace std {
|
|
| 194 |
|
| 195 |
private:
|
| 196 |
mutex_type* pm; // exposition only
|
| 197 |
bool owns; // exposition only
|
| 198 |
};
|
| 199 |
-
|
| 200 |
-
template<class Mutex>
|
| 201 |
-
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
|
| 202 |
}
|
| 203 |
```
|
| 204 |
|
| 205 |
An object of type `unique_lock` controls the ownership of a lockable
|
| 206 |
object within a scope. Ownership of the lockable object may be acquired
|
|
@@ -224,19 +225,16 @@ meets the *Cpp17TimedLockable* requirements. — *end note*]
|
|
| 224 |
|
| 225 |
``` cpp
|
| 226 |
unique_lock() noexcept;
|
| 227 |
```
|
| 228 |
|
| 229 |
-
*Ensures:* `pm ==
|
| 230 |
|
| 231 |
``` cpp
|
| 232 |
explicit unique_lock(mutex_type& m);
|
| 233 |
```
|
| 234 |
|
| 235 |
-
*Preconditions:* If `mutex_type` is not a recursive mutex the calling
|
| 236 |
-
thread does not own the mutex.
|
| 237 |
-
|
| 238 |
*Effects:* Calls `m.lock()`.
|
| 239 |
|
| 240 |
*Ensures:* `pm == addressof(m)` and `owns == true`.
|
| 241 |
|
| 242 |
``` cpp
|
|
@@ -248,35 +246,33 @@ unique_lock(mutex_type& m, defer_lock_t) noexcept;
|
|
| 248 |
``` cpp
|
| 249 |
unique_lock(mutex_type& m, try_to_lock_t);
|
| 250 |
```
|
| 251 |
|
| 252 |
*Preconditions:* The supplied `Mutex` type meets the *Cpp17Lockable*
|
| 253 |
-
requirements [[thread.req.lockable.req]].
|
| 254 |
-
recursive mutex the calling thread does not own the mutex.
|
| 255 |
|
| 256 |
*Effects:* Calls `m.try_lock()`.
|
| 257 |
|
| 258 |
*Ensures:* `pm == addressof(m)` and `owns == res`, where `res` is the
|
| 259 |
value returned by the call to `m.try_lock()`.
|
| 260 |
|
| 261 |
``` cpp
|
| 262 |
unique_lock(mutex_type& m, adopt_lock_t);
|
| 263 |
```
|
| 264 |
|
| 265 |
-
*Preconditions:* The calling thread
|
| 266 |
|
| 267 |
*Ensures:* `pm == addressof(m)` and `owns == true`.
|
| 268 |
|
| 269 |
*Throws:* Nothing.
|
| 270 |
|
| 271 |
``` cpp
|
| 272 |
template<class Clock, class Duration>
|
| 273 |
unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
|
| 274 |
```
|
| 275 |
|
| 276 |
-
*Preconditions:*
|
| 277 |
-
thread does not own the mutex. The supplied `Mutex` type meets the
|
| 278 |
*Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
|
| 279 |
|
| 280 |
*Effects:* Calls `m.try_lock_until(abs_time)`.
|
| 281 |
|
| 282 |
*Ensures:* `pm == addressof(m)` and `owns == res`, where `res` is the
|
|
@@ -285,12 +281,11 @@ value returned by the call to `m.try_lock_until(abs_time)`.
|
|
| 285 |
``` cpp
|
| 286 |
template<class Rep, class Period>
|
| 287 |
unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
|
| 288 |
```
|
| 289 |
|
| 290 |
-
*Preconditions:*
|
| 291 |
-
thread does not own the mutex. The supplied `Mutex` type meets the
|
| 292 |
*Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
|
| 293 |
|
| 294 |
*Effects:* Calls `m.try_lock_for(rel_time)`.
|
| 295 |
|
| 296 |
*Ensures:* `pm == addressof(m)` and `owns == res`, where `res` is the
|
|
@@ -351,14 +346,14 @@ bool try_lock();
|
|
| 351 |
*Preconditions:* The supplied `Mutex` meets the *Cpp17Lockable*
|
| 352 |
requirements [[thread.req.lockable.req]].
|
| 353 |
|
| 354 |
*Effects:* As if by `pm->try_lock()`.
|
| 355 |
|
| 356 |
-
*
|
|
|
|
| 357 |
|
| 358 |
-
*
|
| 359 |
-
to `try_lock()`.
|
| 360 |
|
| 361 |
*Throws:* Any exception thrown by `pm->try_lock()`. `system_error` when
|
| 362 |
an exception is required [[thread.req.exception]].
|
| 363 |
|
| 364 |
*Error conditions:*
|
|
@@ -374,17 +369,17 @@ template<class Clock, class Duration>
|
|
| 374 |
*Preconditions:* The supplied `Mutex` type meets the
|
| 375 |
*Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
|
| 376 |
|
| 377 |
*Effects:* As if by `pm->try_lock_until(abs_time)`.
|
| 378 |
|
| 379 |
-
*
|
|
|
|
| 380 |
|
| 381 |
-
*
|
| 382 |
-
to `try_lock_until(abs_time)`.
|
| 383 |
|
| 384 |
-
*Throws:* Any exception thrown by `pm->try_lock_until()`.
|
| 385 |
-
when an exception is required [[thread.req.exception]].
|
| 386 |
|
| 387 |
*Error conditions:*
|
| 388 |
|
| 389 |
- `operation_not_permitted` — if `pm` is `nullptr`.
|
| 390 |
- `resource_deadlock_would_occur` — if on entry `owns` is `true`.
|
|
@@ -397,17 +392,17 @@ template<class Rep, class Period>
|
|
| 397 |
*Preconditions:* The supplied `Mutex` type meets the
|
| 398 |
*Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
|
| 399 |
|
| 400 |
*Effects:* As if by `pm->try_lock_for(rel_time)`.
|
| 401 |
|
| 402 |
-
*
|
|
|
|
| 403 |
|
| 404 |
-
*
|
| 405 |
-
to `try_lock_for(rel_time)`.
|
| 406 |
|
| 407 |
-
*Throws:* Any exception thrown by `pm->try_lock_for()`.
|
| 408 |
-
when an exception is required [[thread.req.exception]].
|
| 409 |
|
| 410 |
*Error conditions:*
|
| 411 |
|
| 412 |
- `operation_not_permitted` — if `pm` is `nullptr`.
|
| 413 |
- `resource_deadlock_would_occur` — if on entry `owns` is `true`.
|
|
@@ -437,14 +432,14 @@ void swap(unique_lock& u) noexcept;
|
|
| 437 |
|
| 438 |
``` cpp
|
| 439 |
mutex_type* release() noexcept;
|
| 440 |
```
|
| 441 |
|
| 442 |
-
*Returns:* The previous value of `pm`.
|
| 443 |
-
|
| 444 |
*Ensures:* `pm == 0` and `owns == false`.
|
| 445 |
|
|
|
|
|
|
|
| 446 |
``` cpp
|
| 447 |
template<class Mutex>
|
| 448 |
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
|
| 449 |
```
|
| 450 |
|
|
@@ -470,10 +465,12 @@ mutex_type *mutex() const noexcept;
|
|
| 470 |
|
| 471 |
*Returns:* `pm`.
|
| 472 |
|
| 473 |
#### Class template `shared_lock` <a id="thread.lock.shared">[[thread.lock.shared]]</a>
|
| 474 |
|
|
|
|
|
|
|
| 475 |
``` cpp
|
| 476 |
namespace std {
|
| 477 |
template<class Mutex>
|
| 478 |
class shared_lock {
|
| 479 |
public:
|
|
@@ -517,13 +514,10 @@ namespace std {
|
|
| 517 |
|
| 518 |
private:
|
| 519 |
mutex_type* pm; // exposition only
|
| 520 |
bool owns; // exposition only
|
| 521 |
};
|
| 522 |
-
|
| 523 |
-
template<class Mutex>
|
| 524 |
-
void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
|
| 525 |
}
|
| 526 |
```
|
| 527 |
|
| 528 |
An object of type `shared_lock` controls the shared ownership of a
|
| 529 |
lockable object within a scope. Shared ownership of the lockable object
|
|
@@ -531,15 +525,19 @@ may be acquired at construction or after construction, and may be
|
|
| 531 |
transferred, after acquisition, to another `shared_lock` object. Objects
|
| 532 |
of type `shared_lock` are not copyable but are movable. The behavior of
|
| 533 |
a program is undefined if the contained pointer `pm` is not null and the
|
| 534 |
lockable object pointed to by `pm` does not exist for the entire
|
| 535 |
remaining lifetime [[basic.life]] of the `shared_lock` object. The
|
| 536 |
-
supplied `Mutex` type shall meet the
|
| 537 |
-
[[thread.
|
| 538 |
|
| 539 |
-
[*Note 1*: `shared_lock<Mutex>` meets the *
|
| 540 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 541 |
|
| 542 |
##### Constructors, destructor, and assignment <a id="thread.lock.shared.cons">[[thread.lock.shared.cons]]</a>
|
| 543 |
|
| 544 |
``` cpp
|
| 545 |
shared_lock() noexcept;
|
|
@@ -549,13 +547,10 @@ shared_lock() noexcept;
|
|
| 549 |
|
| 550 |
``` cpp
|
| 551 |
explicit shared_lock(mutex_type& m);
|
| 552 |
```
|
| 553 |
|
| 554 |
-
*Preconditions:* The calling thread does not own the mutex for any
|
| 555 |
-
ownership mode.
|
| 556 |
-
|
| 557 |
*Effects:* Calls `m.lock_shared()`.
|
| 558 |
|
| 559 |
*Ensures:* `pm == addressof(m)` and `owns == true`.
|
| 560 |
|
| 561 |
``` cpp
|
|
@@ -566,34 +561,31 @@ shared_lock(mutex_type& m, defer_lock_t) noexcept;
|
|
| 566 |
|
| 567 |
``` cpp
|
| 568 |
shared_lock(mutex_type& m, try_to_lock_t);
|
| 569 |
```
|
| 570 |
|
| 571 |
-
*Preconditions:* The calling thread does not own the mutex for any
|
| 572 |
-
ownership mode.
|
| 573 |
-
|
| 574 |
*Effects:* Calls `m.try_lock_shared()`.
|
| 575 |
|
| 576 |
*Ensures:* `pm == addressof(m)` and `owns == res` where `res` is the
|
| 577 |
value returned by the call to `m.try_lock_shared()`.
|
| 578 |
|
| 579 |
``` cpp
|
| 580 |
shared_lock(mutex_type& m, adopt_lock_t);
|
| 581 |
```
|
| 582 |
|
| 583 |
-
*Preconditions:* The calling thread
|
| 584 |
|
| 585 |
*Ensures:* `pm == addressof(m)` and `owns == true`.
|
| 586 |
|
| 587 |
``` cpp
|
| 588 |
template<class Clock, class Duration>
|
| 589 |
shared_lock(mutex_type& m,
|
| 590 |
const chrono::time_point<Clock, Duration>& abs_time);
|
| 591 |
```
|
| 592 |
|
| 593 |
-
*Preconditions:*
|
| 594 |
-
|
| 595 |
|
| 596 |
*Effects:* Calls `m.try_lock_shared_until(abs_time)`.
|
| 597 |
|
| 598 |
*Ensures:* `pm == addressof(m)` and `owns == res` where `res` is the
|
| 599 |
value returned by the call to `m.try_lock_shared_until(abs_time)`.
|
|
@@ -602,12 +594,12 @@ value returned by the call to `m.try_lock_shared_until(abs_time)`.
|
|
| 602 |
template<class Rep, class Period>
|
| 603 |
shared_lock(mutex_type& m,
|
| 604 |
const chrono::duration<Rep, Period>& rel_time);
|
| 605 |
```
|
| 606 |
|
| 607 |
-
*Preconditions:*
|
| 608 |
-
|
| 609 |
|
| 610 |
*Effects:* Calls `m.try_lock_shared_for(rel_time)`.
|
| 611 |
|
| 612 |
*Ensures:* `pm == addressof(m)` and `owns == res` where `res` is the
|
| 613 |
value returned by the call to `m.try_lock_shared_for(rel_time)`.
|
|
@@ -658,15 +650,15 @@ when an exception is required [[thread.req.exception]].
|
|
| 658 |
bool try_lock();
|
| 659 |
```
|
| 660 |
|
| 661 |
*Effects:* As if by `pm->try_lock_shared()`.
|
| 662 |
|
| 663 |
-
*Returns:* The value returned by the call to `pm->try_lock_shared()`.
|
| 664 |
-
|
| 665 |
*Ensures:* `owns == res`, where `res` is the value returned by the call
|
| 666 |
to `pm->try_lock_shared()`.
|
| 667 |
|
|
|
|
|
|
|
| 668 |
*Throws:* Any exception thrown by `pm->try_lock_shared()`.
|
| 669 |
`system_error` when an exception is required [[thread.req.exception]].
|
| 670 |
|
| 671 |
*Error conditions:*
|
| 672 |
|
|
@@ -676,18 +668,21 @@ to `pm->try_lock_shared()`.
|
|
| 676 |
``` cpp
|
| 677 |
template<class Clock, class Duration>
|
| 678 |
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
|
| 679 |
```
|
| 680 |
|
|
|
|
|
|
|
|
|
|
| 681 |
*Effects:* As if by `pm->try_lock_shared_until(abs_time)`.
|
| 682 |
|
| 683 |
-
*Returns:* The value returned by the call to
|
| 684 |
-
`pm->try_lock_shared_until(abs_time)`.
|
| 685 |
-
|
| 686 |
*Ensures:* `owns == res`, where `res` is the value returned by the call
|
| 687 |
to `pm->try_lock_shared_until(abs_time)`.
|
| 688 |
|
|
|
|
|
|
|
|
|
|
| 689 |
*Throws:* Any exception thrown by `pm->try_lock_shared_until(abs_time)`.
|
| 690 |
`system_error` when an exception is required [[thread.req.exception]].
|
| 691 |
|
| 692 |
*Error conditions:*
|
| 693 |
|
|
@@ -697,18 +692,21 @@ to `pm->try_lock_shared_until(abs_time)`.
|
|
| 697 |
``` cpp
|
| 698 |
template<class Rep, class Period>
|
| 699 |
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
|
| 700 |
```
|
| 701 |
|
|
|
|
|
|
|
|
|
|
| 702 |
*Effects:* As if by `pm->try_lock_shared_for(rel_time)`.
|
| 703 |
|
| 704 |
-
*Returns:* The value returned by the call to
|
| 705 |
-
`pm->try_lock_shared_for(rel_time)`.
|
| 706 |
-
|
| 707 |
*Ensures:* `owns == res`, where `res` is the value returned by the call
|
| 708 |
to `pm->try_lock_shared_for(rel_time)`.
|
| 709 |
|
|
|
|
|
|
|
|
|
|
| 710 |
*Throws:* Any exception thrown by `pm->try_lock_shared_for(rel_time)`.
|
| 711 |
`system_error` when an exception is required [[thread.req.exception]].
|
| 712 |
|
| 713 |
*Error conditions:*
|
| 714 |
|
|
@@ -740,14 +738,14 @@ void swap(shared_lock& sl) noexcept;
|
|
| 740 |
|
| 741 |
``` cpp
|
| 742 |
mutex_type* release() noexcept;
|
| 743 |
```
|
| 744 |
|
| 745 |
-
*Returns:* The previous value of `pm`.
|
| 746 |
-
|
| 747 |
*Ensures:* `pm == nullptr` and `owns == false`.
|
| 748 |
|
|
|
|
|
|
|
| 749 |
``` cpp
|
| 750 |
template<class Mutex>
|
| 751 |
void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
|
| 752 |
```
|
| 753 |
|
|
|
|
| 1 |
### Locks <a id="thread.lock">[[thread.lock]]</a>
|
| 2 |
|
| 3 |
+
#### General <a id="thread.lock.general">[[thread.lock.general]]</a>
|
| 4 |
+
|
| 5 |
A *lock* is an object that holds a reference to a lockable object and
|
| 6 |
may unlock the lockable object during the lock’s destruction (such as
|
| 7 |
when leaving block scope). An execution agent may use a lock to aid in
|
| 8 |
managing ownership of a lockable object in an exception safe manner. A
|
| 9 |
lock is said to *own* a lockable object if it is currently managing the
|
|
|
|
| 63 |
|
| 64 |
``` cpp
|
| 65 |
explicit lock_guard(mutex_type& m);
|
| 66 |
```
|
| 67 |
|
|
|
|
|
|
|
|
|
|
| 68 |
*Effects:* Initializes `pm` with `m`. Calls `m.lock()`.
|
| 69 |
|
| 70 |
``` cpp
|
| 71 |
lock_guard(mutex_type& m, adopt_lock_t);
|
| 72 |
```
|
| 73 |
|
| 74 |
+
*Preconditions:* The calling thread holds a non-shared lock on `m`.
|
| 75 |
|
| 76 |
*Effects:* Initializes `pm` with `m`.
|
| 77 |
|
| 78 |
*Throws:* Nothing.
|
| 79 |
|
| 80 |
``` cpp
|
| 81 |
~lock_guard();
|
| 82 |
```
|
| 83 |
|
| 84 |
+
*Effects:* Equivalent to: `pm.unlock()`
|
| 85 |
|
| 86 |
#### Class template `scoped_lock` <a id="thread.lock.scoped">[[thread.lock.scoped]]</a>
|
| 87 |
|
| 88 |
``` cpp
|
| 89 |
namespace std {
|
| 90 |
template<class... MutexTypes>
|
| 91 |
class scoped_lock {
|
| 92 |
public:
|
| 93 |
+
using mutex_type = see below; // Only if sizeof...(MutexTypes) == 1 is true
|
| 94 |
|
| 95 |
explicit scoped_lock(MutexTypes&... m);
|
| 96 |
explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
|
| 97 |
~scoped_lock();
|
| 98 |
|
|
|
|
| 108 |
An object of type `scoped_lock` controls the ownership of lockable
|
| 109 |
objects within a scope. A `scoped_lock` object maintains ownership of
|
| 110 |
lockable objects throughout the `scoped_lock` object’s lifetime
|
| 111 |
[[basic.life]]. The behavior of a program is undefined if the lockable
|
| 112 |
objects referenced by `pm` do not exist for the entire lifetime of the
|
| 113 |
+
`scoped_lock` object.
|
| 114 |
+
|
| 115 |
+
- If `sizeof...(MutexTypes)` is one, let `Mutex` denote the sole type
|
| 116 |
+
constituting the pack `MutexTypes`. `Mutex` shall meet the
|
| 117 |
+
*Cpp17BasicLockable* requirements [[thread.req.lockable.basic]]. The
|
| 118 |
+
member *typedef-name* `mutex_type` denotes the same type as `Mutex`.
|
| 119 |
+
- Otherwise, all types in the template parameter pack `MutexTypes` shall
|
| 120 |
+
meet the *Cpp17Lockable* requirements [[thread.req.lockable.req]] and
|
| 121 |
+
there is no member `mutex_type`.
|
| 122 |
|
| 123 |
``` cpp
|
| 124 |
explicit scoped_lock(MutexTypes&... m);
|
| 125 |
```
|
| 126 |
|
|
|
|
|
|
|
|
|
|
| 127 |
*Effects:* Initializes `pm` with `tie(m...)`. Then if
|
| 128 |
`sizeof...(MutexTypes)` is `0`, no effects. Otherwise if
|
| 129 |
`sizeof...(MutexTypes)` is `1`, then `m.lock()`. Otherwise,
|
| 130 |
`lock(m...)`.
|
| 131 |
|
| 132 |
``` cpp
|
| 133 |
explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
|
| 134 |
```
|
| 135 |
|
| 136 |
+
*Preconditions:* The calling thread holds a non-shared lock on each
|
| 137 |
+
element of `m`.
|
| 138 |
|
| 139 |
*Effects:* Initializes `pm` with `tie(m...)`.
|
| 140 |
|
| 141 |
*Throws:* Nothing.
|
| 142 |
|
|
|
|
| 147 |
*Effects:* For all `i` in \[`0`, `sizeof...(MutexTypes)`),
|
| 148 |
`get<i>(pm).unlock()`.
|
| 149 |
|
| 150 |
#### Class template `unique_lock` <a id="thread.lock.unique">[[thread.lock.unique]]</a>
|
| 151 |
|
| 152 |
+
##### General <a id="thread.lock.unique.general">[[thread.lock.unique.general]]</a>
|
| 153 |
+
|
| 154 |
``` cpp
|
| 155 |
namespace std {
|
| 156 |
template<class Mutex>
|
| 157 |
class unique_lock {
|
| 158 |
public:
|
|
|
|
| 198 |
|
| 199 |
private:
|
| 200 |
mutex_type* pm; // exposition only
|
| 201 |
bool owns; // exposition only
|
| 202 |
};
|
|
|
|
|
|
|
|
|
|
| 203 |
}
|
| 204 |
```
|
| 205 |
|
| 206 |
An object of type `unique_lock` controls the ownership of a lockable
|
| 207 |
object within a scope. Ownership of the lockable object may be acquired
|
|
|
|
| 225 |
|
| 226 |
``` cpp
|
| 227 |
unique_lock() noexcept;
|
| 228 |
```
|
| 229 |
|
| 230 |
+
*Ensures:* `pm == nullptr` and `owns == false`.
|
| 231 |
|
| 232 |
``` cpp
|
| 233 |
explicit unique_lock(mutex_type& m);
|
| 234 |
```
|
| 235 |
|
|
|
|
|
|
|
|
|
|
| 236 |
*Effects:* Calls `m.lock()`.
|
| 237 |
|
| 238 |
*Ensures:* `pm == addressof(m)` and `owns == true`.
|
| 239 |
|
| 240 |
``` cpp
|
|
|
|
| 246 |
``` cpp
|
| 247 |
unique_lock(mutex_type& m, try_to_lock_t);
|
| 248 |
```
|
| 249 |
|
| 250 |
*Preconditions:* The supplied `Mutex` type meets the *Cpp17Lockable*
|
| 251 |
+
requirements [[thread.req.lockable.req]].
|
|
|
|
| 252 |
|
| 253 |
*Effects:* Calls `m.try_lock()`.
|
| 254 |
|
| 255 |
*Ensures:* `pm == addressof(m)` and `owns == res`, where `res` is the
|
| 256 |
value returned by the call to `m.try_lock()`.
|
| 257 |
|
| 258 |
``` cpp
|
| 259 |
unique_lock(mutex_type& m, adopt_lock_t);
|
| 260 |
```
|
| 261 |
|
| 262 |
+
*Preconditions:* The calling thread holds a non-shared lock on `m`.
|
| 263 |
|
| 264 |
*Ensures:* `pm == addressof(m)` and `owns == true`.
|
| 265 |
|
| 266 |
*Throws:* Nothing.
|
| 267 |
|
| 268 |
``` cpp
|
| 269 |
template<class Clock, class Duration>
|
| 270 |
unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
|
| 271 |
```
|
| 272 |
|
| 273 |
+
*Preconditions:* The supplied `Mutex` type meets the
|
|
|
|
| 274 |
*Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
|
| 275 |
|
| 276 |
*Effects:* Calls `m.try_lock_until(abs_time)`.
|
| 277 |
|
| 278 |
*Ensures:* `pm == addressof(m)` and `owns == res`, where `res` is the
|
|
|
|
| 281 |
``` cpp
|
| 282 |
template<class Rep, class Period>
|
| 283 |
unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
|
| 284 |
```
|
| 285 |
|
| 286 |
+
*Preconditions:* The supplied `Mutex` type meets the
|
|
|
|
| 287 |
*Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
|
| 288 |
|
| 289 |
*Effects:* Calls `m.try_lock_for(rel_time)`.
|
| 290 |
|
| 291 |
*Ensures:* `pm == addressof(m)` and `owns == res`, where `res` is the
|
|
|
|
| 346 |
*Preconditions:* The supplied `Mutex` meets the *Cpp17Lockable*
|
| 347 |
requirements [[thread.req.lockable.req]].
|
| 348 |
|
| 349 |
*Effects:* As if by `pm->try_lock()`.
|
| 350 |
|
| 351 |
+
*Ensures:* `owns == res`, where `res` is the value returned by
|
| 352 |
+
`pm->try_lock()`.
|
| 353 |
|
| 354 |
+
*Returns:* The value returned by `pm->try_lock()`.
|
|
|
|
| 355 |
|
| 356 |
*Throws:* Any exception thrown by `pm->try_lock()`. `system_error` when
|
| 357 |
an exception is required [[thread.req.exception]].
|
| 358 |
|
| 359 |
*Error conditions:*
|
|
|
|
| 369 |
*Preconditions:* The supplied `Mutex` type meets the
|
| 370 |
*Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
|
| 371 |
|
| 372 |
*Effects:* As if by `pm->try_lock_until(abs_time)`.
|
| 373 |
|
| 374 |
+
*Ensures:* `owns == res`, where `res` is the value returned by
|
| 375 |
+
`pm->try_lock_until(abs_time)`.
|
| 376 |
|
| 377 |
+
*Returns:* The value returned by `pm->try_lock_until(abs_time)`.
|
|
|
|
| 378 |
|
| 379 |
+
*Throws:* Any exception thrown by `pm->try_lock_until(abstime)`.
|
| 380 |
+
`system_error` when an exception is required [[thread.req.exception]].
|
| 381 |
|
| 382 |
*Error conditions:*
|
| 383 |
|
| 384 |
- `operation_not_permitted` — if `pm` is `nullptr`.
|
| 385 |
- `resource_deadlock_would_occur` — if on entry `owns` is `true`.
|
|
|
|
| 392 |
*Preconditions:* The supplied `Mutex` type meets the
|
| 393 |
*Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
|
| 394 |
|
| 395 |
*Effects:* As if by `pm->try_lock_for(rel_time)`.
|
| 396 |
|
| 397 |
+
*Ensures:* `owns == res`, where `res` is the value returned by
|
| 398 |
+
`pm->try_lock_for(rel_time)`.
|
| 399 |
|
| 400 |
+
*Returns:* The value returned by `pm->try_lock_for(rel_time)`.
|
|
|
|
| 401 |
|
| 402 |
+
*Throws:* Any exception thrown by `pm->try_lock_for(rel_time)`.
|
| 403 |
+
`system_error` when an exception is required [[thread.req.exception]].
|
| 404 |
|
| 405 |
*Error conditions:*
|
| 406 |
|
| 407 |
- `operation_not_permitted` — if `pm` is `nullptr`.
|
| 408 |
- `resource_deadlock_would_occur` — if on entry `owns` is `true`.
|
|
|
|
| 432 |
|
| 433 |
``` cpp
|
| 434 |
mutex_type* release() noexcept;
|
| 435 |
```
|
| 436 |
|
|
|
|
|
|
|
| 437 |
*Ensures:* `pm == 0` and `owns == false`.
|
| 438 |
|
| 439 |
+
*Returns:* The previous value of `pm`.
|
| 440 |
+
|
| 441 |
``` cpp
|
| 442 |
template<class Mutex>
|
| 443 |
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
|
| 444 |
```
|
| 445 |
|
|
|
|
| 465 |
|
| 466 |
*Returns:* `pm`.
|
| 467 |
|
| 468 |
#### Class template `shared_lock` <a id="thread.lock.shared">[[thread.lock.shared]]</a>
|
| 469 |
|
| 470 |
+
##### General <a id="thread.lock.shared.general">[[thread.lock.shared.general]]</a>
|
| 471 |
+
|
| 472 |
``` cpp
|
| 473 |
namespace std {
|
| 474 |
template<class Mutex>
|
| 475 |
class shared_lock {
|
| 476 |
public:
|
|
|
|
| 514 |
|
| 515 |
private:
|
| 516 |
mutex_type* pm; // exposition only
|
| 517 |
bool owns; // exposition only
|
| 518 |
};
|
|
|
|
|
|
|
|
|
|
| 519 |
}
|
| 520 |
```
|
| 521 |
|
| 522 |
An object of type `shared_lock` controls the shared ownership of a
|
| 523 |
lockable object within a scope. Shared ownership of the lockable object
|
|
|
|
| 525 |
transferred, after acquisition, to another `shared_lock` object. Objects
|
| 526 |
of type `shared_lock` are not copyable but are movable. The behavior of
|
| 527 |
a program is undefined if the contained pointer `pm` is not null and the
|
| 528 |
lockable object pointed to by `pm` does not exist for the entire
|
| 529 |
remaining lifetime [[basic.life]] of the `shared_lock` object. The
|
| 530 |
+
supplied `Mutex` type shall meet the *Cpp17SharedLockable* requirements
|
| 531 |
+
[[thread.req.lockable.shared]].
|
| 532 |
|
| 533 |
+
[*Note 1*: `shared_lock<Mutex>` meets the *Cpp17Lockable* requirements
|
| 534 |
+
[[thread.req.lockable.req]]. If `Mutex` meets the
|
| 535 |
+
*Cpp17SharedTimedLockable* requirements
|
| 536 |
+
[[thread.req.lockable.shared.timed]], `shared_lock<Mutex>` also meets
|
| 537 |
+
the *Cpp17TimedLockable* requirements
|
| 538 |
+
[[thread.req.lockable.timed]]. — *end note*]
|
| 539 |
|
| 540 |
##### Constructors, destructor, and assignment <a id="thread.lock.shared.cons">[[thread.lock.shared.cons]]</a>
|
| 541 |
|
| 542 |
``` cpp
|
| 543 |
shared_lock() noexcept;
|
|
|
|
| 547 |
|
| 548 |
``` cpp
|
| 549 |
explicit shared_lock(mutex_type& m);
|
| 550 |
```
|
| 551 |
|
|
|
|
|
|
|
|
|
|
| 552 |
*Effects:* Calls `m.lock_shared()`.
|
| 553 |
|
| 554 |
*Ensures:* `pm == addressof(m)` and `owns == true`.
|
| 555 |
|
| 556 |
``` cpp
|
|
|
|
| 561 |
|
| 562 |
``` cpp
|
| 563 |
shared_lock(mutex_type& m, try_to_lock_t);
|
| 564 |
```
|
| 565 |
|
|
|
|
|
|
|
|
|
|
| 566 |
*Effects:* Calls `m.try_lock_shared()`.
|
| 567 |
|
| 568 |
*Ensures:* `pm == addressof(m)` and `owns == res` where `res` is the
|
| 569 |
value returned by the call to `m.try_lock_shared()`.
|
| 570 |
|
| 571 |
``` cpp
|
| 572 |
shared_lock(mutex_type& m, adopt_lock_t);
|
| 573 |
```
|
| 574 |
|
| 575 |
+
*Preconditions:* The calling thread holds a shared lock on `m`.
|
| 576 |
|
| 577 |
*Ensures:* `pm == addressof(m)` and `owns == true`.
|
| 578 |
|
| 579 |
``` cpp
|
| 580 |
template<class Clock, class Duration>
|
| 581 |
shared_lock(mutex_type& m,
|
| 582 |
const chrono::time_point<Clock, Duration>& abs_time);
|
| 583 |
```
|
| 584 |
|
| 585 |
+
*Preconditions:* `Mutex` meets the *Cpp17SharedTimedLockable*
|
| 586 |
+
requirements [[thread.req.lockable.shared.timed]].
|
| 587 |
|
| 588 |
*Effects:* Calls `m.try_lock_shared_until(abs_time)`.
|
| 589 |
|
| 590 |
*Ensures:* `pm == addressof(m)` and `owns == res` where `res` is the
|
| 591 |
value returned by the call to `m.try_lock_shared_until(abs_time)`.
|
|
|
|
| 594 |
template<class Rep, class Period>
|
| 595 |
shared_lock(mutex_type& m,
|
| 596 |
const chrono::duration<Rep, Period>& rel_time);
|
| 597 |
```
|
| 598 |
|
| 599 |
+
*Preconditions:* `Mutex` meets the *Cpp17SharedTimedLockable*
|
| 600 |
+
requirements [[thread.req.lockable.shared.timed]].
|
| 601 |
|
| 602 |
*Effects:* Calls `m.try_lock_shared_for(rel_time)`.
|
| 603 |
|
| 604 |
*Ensures:* `pm == addressof(m)` and `owns == res` where `res` is the
|
| 605 |
value returned by the call to `m.try_lock_shared_for(rel_time)`.
|
|
|
|
| 650 |
bool try_lock();
|
| 651 |
```
|
| 652 |
|
| 653 |
*Effects:* As if by `pm->try_lock_shared()`.
|
| 654 |
|
|
|
|
|
|
|
| 655 |
*Ensures:* `owns == res`, where `res` is the value returned by the call
|
| 656 |
to `pm->try_lock_shared()`.
|
| 657 |
|
| 658 |
+
*Returns:* The value returned by the call to `pm->try_lock_shared()`.
|
| 659 |
+
|
| 660 |
*Throws:* Any exception thrown by `pm->try_lock_shared()`.
|
| 661 |
`system_error` when an exception is required [[thread.req.exception]].
|
| 662 |
|
| 663 |
*Error conditions:*
|
| 664 |
|
|
|
|
| 668 |
``` cpp
|
| 669 |
template<class Clock, class Duration>
|
| 670 |
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
|
| 671 |
```
|
| 672 |
|
| 673 |
+
*Preconditions:* `Mutex` meets the *Cpp17SharedTimedLockable*
|
| 674 |
+
requirements [[thread.req.lockable.shared.timed]].
|
| 675 |
+
|
| 676 |
*Effects:* As if by `pm->try_lock_shared_until(abs_time)`.
|
| 677 |
|
|
|
|
|
|
|
|
|
|
| 678 |
*Ensures:* `owns == res`, where `res` is the value returned by the call
|
| 679 |
to `pm->try_lock_shared_until(abs_time)`.
|
| 680 |
|
| 681 |
+
*Returns:* The value returned by the call to
|
| 682 |
+
`pm->try_lock_shared_until(abs_time)`.
|
| 683 |
+
|
| 684 |
*Throws:* Any exception thrown by `pm->try_lock_shared_until(abs_time)`.
|
| 685 |
`system_error` when an exception is required [[thread.req.exception]].
|
| 686 |
|
| 687 |
*Error conditions:*
|
| 688 |
|
|
|
|
| 692 |
``` cpp
|
| 693 |
template<class Rep, class Period>
|
| 694 |
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
|
| 695 |
```
|
| 696 |
|
| 697 |
+
*Preconditions:* `Mutex` meets the *Cpp17SharedTimedLockable*
|
| 698 |
+
requirements [[thread.req.lockable.shared.timed]].
|
| 699 |
+
|
| 700 |
*Effects:* As if by `pm->try_lock_shared_for(rel_time)`.
|
| 701 |
|
|
|
|
|
|
|
|
|
|
| 702 |
*Ensures:* `owns == res`, where `res` is the value returned by the call
|
| 703 |
to `pm->try_lock_shared_for(rel_time)`.
|
| 704 |
|
| 705 |
+
*Returns:* The value returned by the call to
|
| 706 |
+
`pm->try_lock_shared_for(rel_time)`.
|
| 707 |
+
|
| 708 |
*Throws:* Any exception thrown by `pm->try_lock_shared_for(rel_time)`.
|
| 709 |
`system_error` when an exception is required [[thread.req.exception]].
|
| 710 |
|
| 711 |
*Error conditions:*
|
| 712 |
|
|
|
|
| 738 |
|
| 739 |
``` cpp
|
| 740 |
mutex_type* release() noexcept;
|
| 741 |
```
|
| 742 |
|
|
|
|
|
|
|
| 743 |
*Ensures:* `pm == nullptr` and `owns == false`.
|
| 744 |
|
| 745 |
+
*Returns:* The previous value of `pm`.
|
| 746 |
+
|
| 747 |
``` cpp
|
| 748 |
template<class Mutex>
|
| 749 |
void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
|
| 750 |
```
|
| 751 |
|