This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
[thread.lock.algorithm]
# 32 Concurrency support library [[thread]](./#thread)
## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.algorithm)
### 32.6.6 Generic locking algorithms [thread.lock.algorithm]
[🔗](#lib:try_lock)
`template<class L1, class L2, class... L3> int try_lock(L1&, L2&, L3&...);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9310)
*Preconditions*: Each template parameter type meets the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3Cpp17Lockable requirements[thread.req.lockable.req]") requirements[.](#1.sentence-1)
[*Note [1](#note-1)*:
Theunique_lock class template meets these requirements when suitably instantiated[.](#1.sentence-2)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9318)
*Effects*: Calls try_lock() for each argument in order beginning with the
first until all arguments have been processed or a call to try_lock() fails,
either by returning false or by throwing an exception[.](#2.sentence-1)
If a call totry_lock() fails, unlock() is called for all prior arguments
with no further calls to try_lock()[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9326)
*Returns*: -1 if all calls to try_lock() returned true,
otherwise a zero-based index value that indicates the argument for which try_lock() returned false[.](#3.sentence-1)
[🔗](#lib:lock)
`template<class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9339)
*Preconditions*: Each template parameter type meets the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3Cpp17Lockable requirements[thread.req.lockable.req]") requirements[.](#4.sentence-1)
[*Note [2](#note-2)*:
Theunique_lock class template meets these requirements when suitably instantiated[.](#4.sentence-2)
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9347)
*Effects*: All arguments are locked via a sequence of calls to lock(),try_lock(), or unlock() on each argument[.](#5.sentence-1)
The sequence of calls does
not result in deadlock, but is otherwise unspecified[.](#5.sentence-2)
[*Note [3](#note-3)*:
A deadlock avoidance
algorithm such as try-and-back-off can be used, but the specific algorithm is not
specified to avoid over-constraining implementations[.](#5.sentence-3)
— *end note*]
If a call tolock() or try_lock() throws an exception, unlock() is
called for any argument that had been locked by a call to lock() ortry_lock()[.](#5.sentence-4)

View File

@@ -0,0 +1,44 @@
[thread.lock.general]
# 32 Concurrency support library [[thread]](./#thread)
## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.general)
### 32.6.5 Locks [[thread.lock]](thread.lock#general)
#### 32.6.5.1 General [thread.lock.general]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8144)
A [*lock*](#def:lock) is an object that holds a reference to a lockable object and may unlock the
lockable object during the lock's destruction (such as when leaving block scope)[.](#1.sentence-1)
An execution
agent may use a lock to aid in managing ownership of a lockable object in an exception safe
manner[.](#1.sentence-2)
A lock is said to [*own*](#def:own) a lockable object if it is currently managing the
ownership of that lockable object for an execution agent[.](#1.sentence-3)
A lock does not manage the lifetime
of the lockable object it references[.](#1.sentence-4)
[*Note [1](#note-1)*:
Locks are intended to ease the burden of
unlocking the lockable object under both normal and exceptional circumstances[.](#1.sentence-5)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8156)
Some lock constructors take tag types which describe what should be done with the lockable
object during the lock's construction[.](#2.sentence-1)
[🔗](#lib:defer_lock_t)
namespace std {struct defer_lock_t { }; // do not acquire ownership of the mutexstruct try_to_lock_t { }; // try to acquire ownership of the mutex// without blockingstruct adopt_lock_t { }; // assume the calling thread has already// obtained mutex ownership and manage itinline constexpr defer_lock_t defer_lock { }; inline constexpr try_to_lock_t try_to_lock { }; inline constexpr adopt_lock_t adopt_lock { };}

View File

@@ -0,0 +1,78 @@
[thread.lock.guard]
# 32 Concurrency support library [[thread]](./#thread)
## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.guard)
### 32.6.5 Locks [[thread.lock]](thread.lock#guard)
#### 32.6.5.2 Class template lock_guard [thread.lock.guard]
[🔗](#lib:lock_guard)
namespace std {template<class Mutex>class lock_guard {public:using mutex_type = Mutex; explicit lock_guard(mutex_type& m);
lock_guard(mutex_type& m, adopt_lock_t); ~lock_guard();
lock_guard(const lock_guard&) = delete;
lock_guard& operator=(const lock_guard&) = delete; private: mutex_type& pm; // *exposition only*};}
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8203)
An object of type lock_guard controls the ownership of a lockable object
within a scope[.](#1.sentence-1)
A lock_guard object maintains ownership of a lockable
object throughout the lock_guard object's [lifetime](basic.life#def:lifetime "6.8.4Lifetime[basic.life]")[.](#1.sentence-2)
The behavior of a program is undefined if the lockable object referenced bypm does not exist for the entire lifetime of the lock_guard object[.](#1.sentence-3)
The supplied Mutex type shall meet the [*Cpp17BasicLockable*](thread.req.lockable.basic#:Cpp17BasicLockable "32.2.5.2Cpp17BasicLockable requirements[thread.req.lockable.basic]") requirements ([[thread.req.lockable.basic]](thread.req.lockable.basic "32.2.5.2Cpp17BasicLockable requirements"))[.](#1.sentence-4)
[🔗](#lib:lock_guard,constructor)
`explicit lock_guard(mutex_type& m);
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8218)
*Effects*: Initializes pm with m[.](#2.sentence-1)
Calls m.lock()[.](#2.sentence-2)
[🔗](#lib:lock_guard,constructor_)
`lock_guard(mutex_type& m, adopt_lock_t);
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8229)
*Preconditions*: The calling thread holds a non-shared lock on m[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8233)
*Effects*: Initializes pm with m[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8237)
*Throws*: Nothing[.](#5.sentence-1)
[🔗](#lib:lock_guard,destructor)
`~lock_guard();
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8248)
*Effects*: Equivalent to: pm.unlock()

View File

@@ -0,0 +1,91 @@
[thread.lock.scoped]
# 32 Concurrency support library [[thread]](./#thread)
## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.scoped)
### 32.6.5 Locks [[thread.lock]](thread.lock#scoped)
#### 32.6.5.3 Class template scoped_lock [thread.lock.scoped]
[🔗](#lib:scoped_lock)
namespace std {template<class... MutexTypes>class scoped_lock {public:using mutex_type = *see below*; // Only if sizeof...(MutexTypes) == 1 is trueexplicit scoped_lock(MutexTypes&... m); explicit scoped_lock(adopt_lock_t, MutexTypes&... m); ~scoped_lock();
scoped_lock(const scoped_lock&) = delete;
scoped_lock& operator=(const scoped_lock&) = delete; private: tuple<MutexTypes&...> pm; // *exposition only*};}
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8276)
An object of type scoped_lock controls the ownership of lockable objects
within a scope[.](#1.sentence-1)
A scoped_lock object maintains ownership of lockable
objects throughout the scoped_lock object's [lifetime](basic.life#def:lifetime "6.8.4Lifetime[basic.life]")[.](#1.sentence-2)
The behavior of a program is undefined if the lockable objects referenced bypm do not exist for the entire lifetime of the scoped_lock object[.](#1.sentence-3)
- [(1.1)](#1.1)
If sizeof...(MutexTypes) is one,
let Mutex denote the sole type constituting the pack MutexTypes[.](#1.1.sentence-1)
Mutex shall meet the [*Cpp17BasicLockable*](thread.req.lockable.basic#:Cpp17BasicLockable "32.2.5.2Cpp17BasicLockable requirements[thread.req.lockable.basic]") requirements ([[thread.req.lockable.basic]](thread.req.lockable.basic "32.2.5.2Cpp17BasicLockable requirements"))[.](#1.1.sentence-2)
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") mutex_type denotes the same type as Mutex[.](#1.1.sentence-3)
- [(1.2)](#1.2)
Otherwise, all types in the template parameter pack MutexTypes shall meet the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3Cpp17Lockable requirements[thread.req.lockable.req]") requirements ([[thread.req.lockable.req]](thread.req.lockable.req "32.2.5.3Cpp17Lockable requirements"))
and there is no member mutex_type[.](#1.2.sentence-1)
[🔗](#lib:scoped_lock,constructor)
`explicit scoped_lock(MutexTypes&... m);
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8303)
*Effects*: Initializes pm with tie(m...)[.](#2.sentence-1)
Then if sizeof...(MutexTypes) is 0, no effects[.](#2.sentence-2)
Otherwise if sizeof...(MutexTypes) is 1, then m.lock()[.](#2.sentence-3)
Otherwise, lock(m...)[.](#2.sentence-4)
[🔗](#lib:scoped_lock,constructor_)
`explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8317)
*Preconditions*: The calling thread holds a non-shared lock on each element of m[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8321)
*Effects*: Initializes pm with tie(m...)[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8325)
*Throws*: Nothing[.](#5.sentence-1)
[🔗](#lib:scoped_lock,destructor)
`~scoped_lock();
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8336)
*Effects*: For all i in [0, sizeof...(MutexTypes)),get<i>(pm).unlock()[.](#6.sentence-1)

View File

@@ -0,0 +1,525 @@
[thread.lock.shared]
# 32 Concurrency support library [[thread]](./#thread)
## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.shared)
### 32.6.5 Locks [[thread.lock]](thread.lock#shared)
#### 32.6.5.5 Class template shared_lock [thread.lock.shared]
#### [32.6.5.5.1](#general) General [[thread.lock.shared.general]](thread.lock.shared.general)
[🔗](#lib:shared_lock)
namespace std {template<class Mutex>class shared_lock {public:using mutex_type = Mutex; // [[thread.lock.shared.cons]](#cons "32.6.5.5.2Constructors, destructor, and assignment"), construct/copy/destroy shared_lock() noexcept; explicit shared_lock(mutex_type& m); // blocking shared_lock(mutex_type& m, defer_lock_t) noexcept;
shared_lock(mutex_type& m, try_to_lock_t);
shared_lock(mutex_type& m, adopt_lock_t); template<class Clock, class Duration> shared_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time); template<class Rep, class Period> shared_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time); ~shared_lock();
shared_lock(const shared_lock&) = delete;
shared_lock& operator=(const shared_lock&) = delete;
shared_lock(shared_lock&& u) noexcept;
shared_lock& operator=(shared_lock&& u) noexcept; // [[thread.lock.shared.locking]](#locking "32.6.5.5.3Locking"), lockingvoid lock(); // blockingbool try_lock(); template<class Rep, class Period>bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); template<class Clock, class Duration>bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); void unlock(); // [[thread.lock.shared.mod]](#mod "32.6.5.5.4Modifiers"), modifiersvoid swap(shared_lock& u) noexcept;
mutex_type* release() noexcept; // [[thread.lock.shared.obs]](#obs "32.6.5.5.5Observers"), observersbool owns_lock() const noexcept; explicit operator bool() const noexcept;
mutex_type* mutex() const noexcept; private: mutex_type* pm; // *exposition only*bool owns; // *exposition only*};}
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8881)
An object of type shared_lock controls the shared ownership of a
lockable object within a scope[.](#general-1.sentence-1)
Shared ownership of the lockable object may be
acquired at construction or after construction, and may be transferred, after
acquisition, to another shared_lock object[.](#general-1.sentence-2)
Objects of typeshared_lock are not copyable but are movable[.](#general-1.sentence-3)
The behavior of a program
is undefined if the contained pointer pm is not null and the lockable
object pointed to by pm does not exist for the entire remaining
lifetime ([[basic.life]](basic.life "6.8.4Lifetime")) of the shared_lock object[.](#general-1.sentence-4)
The suppliedMutex type shall meet the [*Cpp17SharedLockable*](thread.req.lockable.shared#:Cpp17SharedLockable "32.2.5.5Cpp17SharedLockable requirements[thread.req.lockable.shared]") requirements ([[thread.req.lockable.shared]](thread.req.lockable.shared "32.2.5.5Cpp17SharedLockable requirements"))[.](#general-1.sentence-5)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8893)
[*Note [1](#general-note-1)*:
shared_lock<Mutex> meets the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3Cpp17Lockable requirements[thread.req.lockable.req]") requirements ([[thread.req.lockable.req]](thread.req.lockable.req "32.2.5.3Cpp17Lockable requirements"))[.](#general-2.sentence-1)
If Mutex meets the [*Cpp17SharedTimedLockable*](thread.req.lockable.shared.timed#:Cpp17SharedTimedLockable "32.2.5.6Cpp17SharedTimedLockable requirements[thread.req.lockable.shared.timed]") requirements ([[thread.req.lockable.shared.timed]](thread.req.lockable.shared.timed "32.2.5.6Cpp17SharedTimedLockable requirements")),shared_lock<Mutex> also meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4Cpp17TimedLockable requirements[thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4Cpp17TimedLockable requirements"))[.](#general-2.sentence-2)
— *end note*]
#### [32.6.5.5.2](#cons) Constructors, destructor, and assignment [[thread.lock.shared.cons]](thread.lock.shared.cons)
[🔗](#lib:shared_lock,constructor)
`shared_lock() noexcept;
`
[1](#cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8911)
*Postconditions*: pm == nullptr and owns == false[.](#cons-1.sentence-1)
[🔗](#lib:shared_lock,constructor_)
`explicit shared_lock(mutex_type& m);
`
[2](#cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8922)
*Effects*: Calls m.lock_shared()[.](#cons-2.sentence-1)
[3](#cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8926)
*Postconditions*: pm == addressof(m) and owns == true[.](#cons-3.sentence-1)
[🔗](#lib:shared_lock,constructor__)
`shared_lock(mutex_type& m, defer_lock_t) noexcept;
`
[4](#cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8937)
*Postconditions*: pm == addressof(m) and owns == false[.](#cons-4.sentence-1)
[🔗](#lib:shared_lock,constructor___)
`shared_lock(mutex_type& m, try_to_lock_t);
`
[5](#cons-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8948)
*Effects*: Calls m.try_lock_shared()[.](#cons-5.sentence-1)
[6](#cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8952)
*Postconditions*: pm == addressof(m) and owns == res where res is the
value returned by the call to m.try_lock_shared()[.](#cons-6.sentence-1)
[🔗](#lib:shared_lock,constructor____)
`shared_lock(mutex_type& m, adopt_lock_t);
`
[7](#cons-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8965)
*Preconditions*: The calling thread holds a shared lock on m[.](#cons-7.sentence-1)
[8](#cons-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8969)
*Postconditions*: pm == addressof(m) and owns == true[.](#cons-8.sentence-1)
[🔗](#lib:shared_lock,constructor_____)
`template<class Clock, class Duration>
shared_lock(mutex_type& m,
const chrono::time_point<Clock, Duration>& abs_time);
`
[9](#cons-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8982)
*Preconditions*: Mutex meets the [*Cpp17SharedTimedLockable*](thread.req.lockable.shared.timed#:Cpp17SharedTimedLockable "32.2.5.6Cpp17SharedTimedLockable requirements[thread.req.lockable.shared.timed]") requirements ([[thread.req.lockable.shared.timed]](thread.req.lockable.shared.timed "32.2.5.6Cpp17SharedTimedLockable requirements"))[.](#cons-9.sentence-1)
[10](#cons-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8987)
*Effects*: Calls m.try_lock_shared_until(abs_time)[.](#cons-10.sentence-1)
[11](#cons-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8991)
*Postconditions*: pm == addressof(m) and owns == res where res is the value returned by the call to m.try_lock_shared_until(abs_time)[.](#cons-11.sentence-1)
[🔗](#lib:shared_lock,constructor______)
`template<class Rep, class Period>
shared_lock(mutex_type& m,
const chrono::duration<Rep, Period>& rel_time);
`
[12](#cons-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9006)
*Preconditions*: Mutex meets the [*Cpp17SharedTimedLockable*](thread.req.lockable.shared.timed#:Cpp17SharedTimedLockable "32.2.5.6Cpp17SharedTimedLockable requirements[thread.req.lockable.shared.timed]") requirements ([[thread.req.lockable.shared.timed]](thread.req.lockable.shared.timed "32.2.5.6Cpp17SharedTimedLockable requirements"))[.](#cons-12.sentence-1)
[13](#cons-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9011)
*Effects*: Calls m.try_lock_shared_for(rel_time)[.](#cons-13.sentence-1)
[14](#cons-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9015)
*Postconditions*: pm == addressof(m) and owns == res where res is
the value returned by the call to m.try_lock_shared_for(rel_time)[.](#cons-14.sentence-1)
[🔗](#lib:shared_lock,destructor)
`~shared_lock();
`
[15](#cons-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9028)
*Effects*: If owns calls pm->unlock_shared()[.](#cons-15.sentence-1)
[🔗](#lib:shared_lock,constructor_______)
`shared_lock(shared_lock&& sl) noexcept;
`
[16](#cons-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9039)
*Postconditions*: pm == sl_p.pm and owns == sl_p.owns (wheresl_p is the state of sl just prior to this construction),sl.pm == nullptr and sl.owns == false[.](#cons-16.sentence-1)
[🔗](#lib:operator=,shared_lock)
`shared_lock& operator=(shared_lock&& sl) noexcept;
`
[17](#cons-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9052)
*Effects*: Equivalent to: shared_lock(std::move(sl)).swap(*this)
[18](#cons-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9056)
*Returns*: *this[.](#cons-18.sentence-1)
#### [32.6.5.5.3](#locking) Locking [[thread.lock.shared.locking]](thread.lock.shared.locking)
[🔗](#lib:lock,shared_lock)
`void lock();
`
[1](#locking-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9069)
*Effects*: As if by pm->lock_shared()[.](#locking-1.sentence-1)
[2](#locking-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9073)
*Postconditions*: owns == true[.](#locking-2.sentence-1)
[3](#locking-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9077)
*Throws*: Any exception thrown by pm->lock_shared()[.](#locking-3.sentence-1)
system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#locking-3.sentence-2)
[4](#locking-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9082)
*Error conditions*:
- [(4.1)](#locking-4.1)
operation_not_permitted — if pm is nullptr[.](#locking-4.1.sentence-1)
- [(4.2)](#locking-4.2)
resource_deadlock_would_occur — if on entry owns istrue[.](#locking-4.2.sentence-1)
[🔗](#lib:try_lock,shared_lock)
`bool try_lock();
`
[5](#locking-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9097)
*Effects*: As if by pm->try_lock_shared()[.](#locking-5.sentence-1)
[6](#locking-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9101)
*Postconditions*: owns == res, where res is the value returned by
the call to pm->try_lock_shared()[.](#locking-6.sentence-1)
[7](#locking-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9106)
*Returns*: The value returned by the call to pm->try_lock_shared()[.](#locking-7.sentence-1)
[8](#locking-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9110)
*Throws*: Any exception thrown by pm->try_lock_shared()[.](#locking-8.sentence-1)
system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#locking-8.sentence-2)
[9](#locking-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9115)
*Error conditions*:
- [(9.1)](#locking-9.1)
operation_not_permitted — if pm is nullptr[.](#locking-9.1.sentence-1)
- [(9.2)](#locking-9.2)
resource_deadlock_would_occur — if on entry owns istrue[.](#locking-9.2.sentence-1)
[🔗](#lib:try_lock_until,shared_lock)
`template<class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
`
[10](#locking-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9131)
*Preconditions*: Mutex meets the [*Cpp17SharedTimedLockable*](thread.req.lockable.shared.timed#:Cpp17SharedTimedLockable "32.2.5.6Cpp17SharedTimedLockable requirements[thread.req.lockable.shared.timed]") requirements ([[thread.req.lockable.shared.timed]](thread.req.lockable.shared.timed "32.2.5.6Cpp17SharedTimedLockable requirements"))[.](#locking-10.sentence-1)
[11](#locking-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9136)
*Effects*: As if by pm->try_lock_shared_until(abs_time)[.](#locking-11.sentence-1)
[12](#locking-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9140)
*Postconditions*: owns == res, where res is the value returned by
the call to pm->try_lock_shared_until(abs_time)[.](#locking-12.sentence-1)
[13](#locking-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9145)
*Returns*: The value returned by the call topm->try_lock_shared_until(abs_time)[.](#locking-13.sentence-1)
[14](#locking-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9150)
*Throws*: Any exception thrown by pm->try_lock_shared_until(abs_time)[.](#locking-14.sentence-1)
system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#locking-14.sentence-2)
[15](#locking-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9155)
*Error conditions*:
- [(15.1)](#locking-15.1)
operation_not_permitted — if pm is nullptr[.](#locking-15.1.sentence-1)
- [(15.2)](#locking-15.2)
resource_deadlock_would_occur — if on entry owns istrue[.](#locking-15.2.sentence-1)
[🔗](#lib:try_lock_for,shared_lock)
`template<class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
`
[16](#locking-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9171)
*Preconditions*: Mutex meets the [*Cpp17SharedTimedLockable*](thread.req.lockable.shared.timed#:Cpp17SharedTimedLockable "32.2.5.6Cpp17SharedTimedLockable requirements[thread.req.lockable.shared.timed]") requirements ([[thread.req.lockable.shared.timed]](thread.req.lockable.shared.timed "32.2.5.6Cpp17SharedTimedLockable requirements"))[.](#locking-16.sentence-1)
[17](#locking-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9176)
*Effects*: As if by pm->try_lock_shared_for(rel_time)[.](#locking-17.sentence-1)
[18](#locking-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9180)
*Postconditions*: owns == res, where res is the value returned by the call to pm->try_lock_shared_for(rel_time)[.](#locking-18.sentence-1)
[19](#locking-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9184)
*Returns*: The value returned by the call to pm->try_lock_shared_for(rel_time)[.](#locking-19.sentence-1)
[20](#locking-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9188)
*Throws*: Any exception thrown by pm->try_lock_shared_for(rel_time)[.](#locking-20.sentence-1)
system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#locking-20.sentence-2)
[21](#locking-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9192)
*Error conditions*:
- [(21.1)](#locking-21.1)
operation_not_permitted — if pm is nullptr[.](#locking-21.1.sentence-1)
- [(21.2)](#locking-21.2)
resource_deadlock_would_occur — if on entry owns istrue[.](#locking-21.2.sentence-1)
[🔗](#lib:unlock,shared_lock)
`void unlock();
`
[22](#locking-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9207)
*Effects*: As if by pm->unlock_shared()[.](#locking-22.sentence-1)
[23](#locking-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9211)
*Postconditions*: owns == false[.](#locking-23.sentence-1)
[24](#locking-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9215)
*Throws*: system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#locking-24.sentence-1)
[25](#locking-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9219)
*Error conditions*:
- [(25.1)](#locking-25.1)
operation_not_permitted — if on entry owns isfalse[.](#locking-25.sentence-1)
#### [32.6.5.5.4](#mod) Modifiers [[thread.lock.shared.mod]](thread.lock.shared.mod)
[🔗](#lib:swap,shared_lock)
`void swap(shared_lock& sl) noexcept;
`
[1](#mod-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9235)
*Effects*: Swaps the data members of *this and sl[.](#mod-1.sentence-1)
[🔗](#lib:release,shared_lock)
`mutex_type* release() noexcept;
`
[2](#mod-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9246)
*Postconditions*: pm == nullptr and owns == false[.](#mod-2.sentence-1)
[3](#mod-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9250)
*Returns*: The previous value of pm[.](#mod-3.sentence-1)
[🔗](#lib:swap,shared_lock_)
`template<class Mutex>
void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
`
[4](#mod-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9262)
*Effects*: As if by x.swap(y)[.](#mod-4.sentence-1)
#### [32.6.5.5.5](#obs) Observers [[thread.lock.shared.obs]](thread.lock.shared.obs)
[🔗](#lib:owns_lock,shared_lock)
`bool owns_lock() const noexcept;
`
[1](#obs-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9275)
*Returns*: owns[.](#obs-1.sentence-1)
[🔗](#lib:operator_bool,shared_lock)
`explicit operator bool() const noexcept;
`
[2](#obs-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9286)
*Returns*: owns[.](#obs-2.sentence-1)
[🔗](#lib:mutex,shared_lock)
`mutex_type* mutex() const noexcept;
`
[3](#obs-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9297)
*Returns*: pm[.](#obs-3.sentence-1)

View File

@@ -0,0 +1,175 @@
[thread.lock.shared.cons]
# 32 Concurrency support library [[thread]](./#thread)
## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.shared.cons)
### 32.6.5 Locks [[thread.lock]](thread.lock#shared.cons)
#### 32.6.5.5 Class template shared_lock [[thread.lock.shared]](thread.lock.shared#cons)
#### 32.6.5.5.2 Constructors, destructor, and assignment [thread.lock.shared.cons]
[🔗](#lib:shared_lock,constructor)
`shared_lock() noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8911)
*Postconditions*: pm == nullptr and owns == false[.](#1.sentence-1)
[🔗](#lib:shared_lock,constructor_)
`explicit shared_lock(mutex_type& m);
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8922)
*Effects*: Calls m.lock_shared()[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8926)
*Postconditions*: pm == addressof(m) and owns == true[.](#3.sentence-1)
[🔗](#lib:shared_lock,constructor__)
`shared_lock(mutex_type& m, defer_lock_t) noexcept;
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8937)
*Postconditions*: pm == addressof(m) and owns == false[.](#4.sentence-1)
[🔗](#lib:shared_lock,constructor___)
`shared_lock(mutex_type& m, try_to_lock_t);
`
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8948)
*Effects*: Calls m.try_lock_shared()[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8952)
*Postconditions*: pm == addressof(m) and owns == res where res is the
value returned by the call to m.try_lock_shared()[.](#6.sentence-1)
[🔗](#lib:shared_lock,constructor____)
`shared_lock(mutex_type& m, adopt_lock_t);
`
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8965)
*Preconditions*: The calling thread holds a shared lock on m[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8969)
*Postconditions*: pm == addressof(m) and owns == true[.](#8.sentence-1)
[🔗](#lib:shared_lock,constructor_____)
`template<class Clock, class Duration>
shared_lock(mutex_type& m,
const chrono::time_point<Clock, Duration>& abs_time);
`
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8982)
*Preconditions*: Mutex meets the [*Cpp17SharedTimedLockable*](thread.req.lockable.shared.timed#:Cpp17SharedTimedLockable "32.2.5.6Cpp17SharedTimedLockable requirements[thread.req.lockable.shared.timed]") requirements ([[thread.req.lockable.shared.timed]](thread.req.lockable.shared.timed "32.2.5.6Cpp17SharedTimedLockable requirements"))[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8987)
*Effects*: Calls m.try_lock_shared_until(abs_time)[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8991)
*Postconditions*: pm == addressof(m) and owns == res where res is the value returned by the call to m.try_lock_shared_until(abs_time)[.](#11.sentence-1)
[🔗](#lib:shared_lock,constructor______)
`template<class Rep, class Period>
shared_lock(mutex_type& m,
const chrono::duration<Rep, Period>& rel_time);
`
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9006)
*Preconditions*: Mutex meets the [*Cpp17SharedTimedLockable*](thread.req.lockable.shared.timed#:Cpp17SharedTimedLockable "32.2.5.6Cpp17SharedTimedLockable requirements[thread.req.lockable.shared.timed]") requirements ([[thread.req.lockable.shared.timed]](thread.req.lockable.shared.timed "32.2.5.6Cpp17SharedTimedLockable requirements"))[.](#12.sentence-1)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9011)
*Effects*: Calls m.try_lock_shared_for(rel_time)[.](#13.sentence-1)
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9015)
*Postconditions*: pm == addressof(m) and owns == res where res is
the value returned by the call to m.try_lock_shared_for(rel_time)[.](#14.sentence-1)
[🔗](#lib:shared_lock,destructor)
`~shared_lock();
`
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9028)
*Effects*: If owns calls pm->unlock_shared()[.](#15.sentence-1)
[🔗](#lib:shared_lock,constructor_______)
`shared_lock(shared_lock&& sl) noexcept;
`
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9039)
*Postconditions*: pm == sl_p.pm and owns == sl_p.owns (wheresl_p is the state of sl just prior to this construction),sl.pm == nullptr and sl.owns == false[.](#16.sentence-1)
[🔗](#lib:operator=,shared_lock)
`shared_lock& operator=(shared_lock&& sl) noexcept;
`
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9052)
*Effects*: Equivalent to: shared_lock(std::move(sl)).swap(*this)
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9056)
*Returns*: *this[.](#18.sentence-1)

View File

@@ -0,0 +1,57 @@
[thread.lock.shared.general]
# 32 Concurrency support library [[thread]](./#thread)
## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.shared.general)
### 32.6.5 Locks [[thread.lock]](thread.lock#shared.general)
#### 32.6.5.5 Class template shared_lock [[thread.lock.shared]](thread.lock.shared#general)
#### 32.6.5.5.1 General [thread.lock.shared.general]
[🔗](#lib:shared_lock)
namespace std {template<class Mutex>class shared_lock {public:using mutex_type = Mutex; // [[thread.lock.shared.cons]](thread.lock.shared.cons "32.6.5.5.2Constructors, destructor, and assignment"), construct/copy/destroy shared_lock() noexcept; explicit shared_lock(mutex_type& m); // blocking shared_lock(mutex_type& m, defer_lock_t) noexcept;
shared_lock(mutex_type& m, try_to_lock_t);
shared_lock(mutex_type& m, adopt_lock_t); template<class Clock, class Duration> shared_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time); template<class Rep, class Period> shared_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time); ~shared_lock();
shared_lock(const shared_lock&) = delete;
shared_lock& operator=(const shared_lock&) = delete;
shared_lock(shared_lock&& u) noexcept;
shared_lock& operator=(shared_lock&& u) noexcept; // [[thread.lock.shared.locking]](thread.lock.shared.locking "32.6.5.5.3Locking"), lockingvoid lock(); // blockingbool try_lock(); template<class Rep, class Period>bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); template<class Clock, class Duration>bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); void unlock(); // [[thread.lock.shared.mod]](thread.lock.shared.mod "32.6.5.5.4Modifiers"), modifiersvoid swap(shared_lock& u) noexcept;
mutex_type* release() noexcept; // [[thread.lock.shared.obs]](thread.lock.shared.obs "32.6.5.5.5Observers"), observersbool owns_lock() const noexcept; explicit operator bool() const noexcept;
mutex_type* mutex() const noexcept; private: mutex_type* pm; // *exposition only*bool owns; // *exposition only*};}
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8881)
An object of type shared_lock controls the shared ownership of a
lockable object within a scope[.](#1.sentence-1)
Shared ownership of the lockable object may be
acquired at construction or after construction, and may be transferred, after
acquisition, to another shared_lock object[.](#1.sentence-2)
Objects of typeshared_lock are not copyable but are movable[.](#1.sentence-3)
The behavior of a program
is undefined if the contained pointer pm is not null and the lockable
object pointed to by pm does not exist for the entire remaining
lifetime ([[basic.life]](basic.life "6.8.4Lifetime")) of the shared_lock object[.](#1.sentence-4)
The suppliedMutex type shall meet the [*Cpp17SharedLockable*](thread.req.lockable.shared#:Cpp17SharedLockable "32.2.5.5Cpp17SharedLockable requirements[thread.req.lockable.shared]") requirements ([[thread.req.lockable.shared]](thread.req.lockable.shared "32.2.5.5Cpp17SharedLockable requirements"))[.](#1.sentence-5)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8893)
[*Note [1](#note-1)*:
shared_lock<Mutex> meets the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3Cpp17Lockable requirements[thread.req.lockable.req]") requirements ([[thread.req.lockable.req]](thread.req.lockable.req "32.2.5.3Cpp17Lockable requirements"))[.](#2.sentence-1)
If Mutex meets the [*Cpp17SharedTimedLockable*](thread.req.lockable.shared.timed#:Cpp17SharedTimedLockable "32.2.5.6Cpp17SharedTimedLockable requirements[thread.req.lockable.shared.timed]") requirements ([[thread.req.lockable.shared.timed]](thread.req.lockable.shared.timed "32.2.5.6Cpp17SharedTimedLockable requirements")),shared_lock<Mutex> also meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4Cpp17TimedLockable requirements[thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4Cpp17TimedLockable requirements"))[.](#2.sentence-2)
— *end note*]

View File

@@ -0,0 +1,234 @@
[thread.lock.shared.locking]
# 32 Concurrency support library [[thread]](./#thread)
## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.shared.locking)
### 32.6.5 Locks [[thread.lock]](thread.lock#shared.locking)
#### 32.6.5.5 Class template shared_lock [[thread.lock.shared]](thread.lock.shared#locking)
#### 32.6.5.5.3 Locking [thread.lock.shared.locking]
[🔗](#lib:lock,shared_lock)
`void lock();
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9069)
*Effects*: As if by pm->lock_shared()[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9073)
*Postconditions*: owns == true[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9077)
*Throws*: Any exception thrown by pm->lock_shared()[.](#3.sentence-1)
system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#3.sentence-2)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9082)
*Error conditions*:
- [(4.1)](#4.1)
operation_not_permitted — if pm is nullptr[.](#4.1.sentence-1)
- [(4.2)](#4.2)
resource_deadlock_would_occur — if on entry owns istrue[.](#4.2.sentence-1)
[🔗](#lib:try_lock,shared_lock)
`bool try_lock();
`
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9097)
*Effects*: As if by pm->try_lock_shared()[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9101)
*Postconditions*: owns == res, where res is the value returned by
the call to pm->try_lock_shared()[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9106)
*Returns*: The value returned by the call to pm->try_lock_shared()[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9110)
*Throws*: Any exception thrown by pm->try_lock_shared()[.](#8.sentence-1)
system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#8.sentence-2)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9115)
*Error conditions*:
- [(9.1)](#9.1)
operation_not_permitted — if pm is nullptr[.](#9.1.sentence-1)
- [(9.2)](#9.2)
resource_deadlock_would_occur — if on entry owns istrue[.](#9.2.sentence-1)
[🔗](#lib:try_lock_until,shared_lock)
`template<class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
`
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9131)
*Preconditions*: Mutex meets the [*Cpp17SharedTimedLockable*](thread.req.lockable.shared.timed#:Cpp17SharedTimedLockable "32.2.5.6Cpp17SharedTimedLockable requirements[thread.req.lockable.shared.timed]") requirements ([[thread.req.lockable.shared.timed]](thread.req.lockable.shared.timed "32.2.5.6Cpp17SharedTimedLockable requirements"))[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9136)
*Effects*: As if by pm->try_lock_shared_until(abs_time)[.](#11.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9140)
*Postconditions*: owns == res, where res is the value returned by
the call to pm->try_lock_shared_until(abs_time)[.](#12.sentence-1)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9145)
*Returns*: The value returned by the call topm->try_lock_shared_until(abs_time)[.](#13.sentence-1)
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9150)
*Throws*: Any exception thrown by pm->try_lock_shared_until(abs_time)[.](#14.sentence-1)
system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#14.sentence-2)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9155)
*Error conditions*:
- [(15.1)](#15.1)
operation_not_permitted — if pm is nullptr[.](#15.1.sentence-1)
- [(15.2)](#15.2)
resource_deadlock_would_occur — if on entry owns istrue[.](#15.2.sentence-1)
[🔗](#lib:try_lock_for,shared_lock)
`template<class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
`
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9171)
*Preconditions*: Mutex meets the [*Cpp17SharedTimedLockable*](thread.req.lockable.shared.timed#:Cpp17SharedTimedLockable "32.2.5.6Cpp17SharedTimedLockable requirements[thread.req.lockable.shared.timed]") requirements ([[thread.req.lockable.shared.timed]](thread.req.lockable.shared.timed "32.2.5.6Cpp17SharedTimedLockable requirements"))[.](#16.sentence-1)
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9176)
*Effects*: As if by pm->try_lock_shared_for(rel_time)[.](#17.sentence-1)
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9180)
*Postconditions*: owns == res, where res is the value returned by the call to pm->try_lock_shared_for(rel_time)[.](#18.sentence-1)
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9184)
*Returns*: The value returned by the call to pm->try_lock_shared_for(rel_time)[.](#19.sentence-1)
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9188)
*Throws*: Any exception thrown by pm->try_lock_shared_for(rel_time)[.](#20.sentence-1)
system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#20.sentence-2)
[21](#21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9192)
*Error conditions*:
- [(21.1)](#21.1)
operation_not_permitted — if pm is nullptr[.](#21.1.sentence-1)
- [(21.2)](#21.2)
resource_deadlock_would_occur — if on entry owns istrue[.](#21.2.sentence-1)
[🔗](#lib:unlock,shared_lock)
`void unlock();
`
[22](#22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9207)
*Effects*: As if by pm->unlock_shared()[.](#22.sentence-1)
[23](#23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9211)
*Postconditions*: owns == false[.](#23.sentence-1)
[24](#24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9215)
*Throws*: system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#24.sentence-1)
[25](#25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9219)
*Error conditions*:
- [(25.1)](#25.1)
operation_not_permitted — if on entry owns isfalse[.](#25.sentence-1)

View File

@@ -0,0 +1,51 @@
[thread.lock.shared.mod]
# 32 Concurrency support library [[thread]](./#thread)
## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.shared.mod)
### 32.6.5 Locks [[thread.lock]](thread.lock#shared.mod)
#### 32.6.5.5 Class template shared_lock [[thread.lock.shared]](thread.lock.shared#mod)
#### 32.6.5.5.4 Modifiers [thread.lock.shared.mod]
[🔗](#lib:swap,shared_lock)
`void swap(shared_lock& sl) noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9235)
*Effects*: Swaps the data members of *this and sl[.](#1.sentence-1)
[🔗](#lib:release,shared_lock)
`mutex_type* release() noexcept;
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9246)
*Postconditions*: pm == nullptr and owns == false[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9250)
*Returns*: The previous value of pm[.](#3.sentence-1)
[🔗](#lib:swap,shared_lock_)
`template<class Mutex>
void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9262)
*Effects*: As if by x.swap(y)[.](#4.sentence-1)

View File

@@ -0,0 +1,44 @@
[thread.lock.shared.obs]
# 32 Concurrency support library [[thread]](./#thread)
## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.shared.obs)
### 32.6.5 Locks [[thread.lock]](thread.lock#shared.obs)
#### 32.6.5.5 Class template shared_lock [[thread.lock.shared]](thread.lock.shared#obs)
#### 32.6.5.5.5 Observers [thread.lock.shared.obs]
[🔗](#lib:owns_lock,shared_lock)
`bool owns_lock() const noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9275)
*Returns*: owns[.](#1.sentence-1)
[🔗](#lib:operator_bool,shared_lock)
`explicit operator bool() const noexcept;
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9286)
*Returns*: owns[.](#2.sentence-1)
[🔗](#lib:mutex,shared_lock)
`mutex_type* mutex() const noexcept;
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9297)
*Returns*: pm[.](#3.sentence-1)

View File

@@ -0,0 +1,548 @@
[thread.lock.unique]
# 32 Concurrency support library [[thread]](./#thread)
## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.unique)
### 32.6.5 Locks [[thread.lock]](thread.lock#unique)
#### 32.6.5.4 Class template unique_lock [thread.lock.unique]
#### [32.6.5.4.1](#general) General [[thread.lock.unique.general]](thread.lock.unique.general)
[🔗](#lib:unique_lock)
namespace std {template<class Mutex>class unique_lock {public:using mutex_type = Mutex; // [[thread.lock.unique.cons]](#cons "32.6.5.4.2Constructors, destructor, and assignment"), construct/copy/destroy unique_lock() noexcept; explicit unique_lock(mutex_type& m);
unique_lock(mutex_type& m, defer_lock_t) noexcept;
unique_lock(mutex_type& m, try_to_lock_t);
unique_lock(mutex_type& m, adopt_lock_t); template<class Clock, class Duration> unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time); template<class Rep, class Period> unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time); ~unique_lock();
unique_lock(const unique_lock&) = delete;
unique_lock& operator=(const unique_lock&) = delete;
unique_lock(unique_lock&& u) noexcept;
unique_lock& operator=(unique_lock&& u) noexcept; // [[thread.lock.unique.locking]](#locking "32.6.5.4.3Locking"), lockingvoid lock(); bool try_lock(); template<class Rep, class Period>bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); template<class Clock, class Duration>bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); void unlock(); // [[thread.lock.unique.mod]](#mod "32.6.5.4.4Modifiers"), modifiersvoid swap(unique_lock& u) noexcept;
mutex_type* release() noexcept; // [[thread.lock.unique.obs]](#obs "32.6.5.4.5Observers"), observersbool owns_lock() const noexcept; explicit operator bool() const noexcept;
mutex_type* mutex() const noexcept; private: mutex_type* pm; // *exposition only*bool owns; // *exposition only*};}
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8399)
An object of type unique_lock controls the ownership of a lockable
object within a scope[.](#general-1.sentence-1)
Ownership of the lockable object may be acquired at
construction or after construction, and may be transferred, after
acquisition, to another unique_lock object[.](#general-1.sentence-2)
Objects of type unique_lock are not
copyable but are movable[.](#general-1.sentence-3)
The behavior of a program is undefined if the contained pointerpm is not null and the lockable object pointed
to by pm does not exist for the entire remaining
lifetime ([[basic.life]](basic.life "6.8.4Lifetime")) of the unique_lock object[.](#general-1.sentence-4)
The suppliedMutex type shall meet the [*Cpp17BasicLockable*](thread.req.lockable.basic#:Cpp17BasicLockable "32.2.5.2Cpp17BasicLockable requirements[thread.req.lockable.basic]") requirements ([[thread.req.lockable.basic]](thread.req.lockable.basic "32.2.5.2Cpp17BasicLockable requirements"))[.](#general-1.sentence-5)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8411)
[*Note [1](#general-note-1)*:
unique_lock<Mutex> meets the [*Cpp17BasicLockable*](thread.req.lockable.basic#:Cpp17BasicLockable "32.2.5.2Cpp17BasicLockable requirements[thread.req.lockable.basic]") requirements[.](#general-2.sentence-1)
If Mutex meets the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3Cpp17Lockable requirements[thread.req.lockable.req]") requirements ([[thread.req.lockable.req]](thread.req.lockable.req "32.2.5.3Cpp17Lockable requirements")),unique_lock<Mutex> also meets the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3Cpp17Lockable requirements[thread.req.lockable.req]") requirements;
if Mutex meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4Cpp17TimedLockable requirements[thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4Cpp17TimedLockable requirements")),unique_lock<Mutex> also meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4Cpp17TimedLockable requirements[thread.req.lockable.timed]") requirements[.](#general-2.sentence-2)
— *end note*]
#### [32.6.5.4.2](#cons) Constructors, destructor, and assignment [[thread.lock.unique.cons]](thread.lock.unique.cons)
[🔗](#lib:unique_lock,constructor)
`unique_lock() noexcept;
`
[1](#cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8429)
*Postconditions*: pm == nullptr and owns == false[.](#cons-1.sentence-1)
[🔗](#lib:unique_lock,constructor_)
`explicit unique_lock(mutex_type& m);
`
[2](#cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8440)
*Effects*: Calls m.lock()[.](#cons-2.sentence-1)
[3](#cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8444)
*Postconditions*: pm == addressof(m) and owns == true[.](#cons-3.sentence-1)
[🔗](#lib:unique_lock,constructor__)
`unique_lock(mutex_type& m, defer_lock_t) noexcept;
`
[4](#cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8455)
*Postconditions*: pm == addressof(m) and owns == false[.](#cons-4.sentence-1)
[🔗](#lib:unique_lock,constructor___)
`unique_lock(mutex_type& m, try_to_lock_t);
`
[5](#cons-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8466)
*Preconditions*: The supplied Mutex type meets the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3Cpp17Lockable requirements[thread.req.lockable.req]") requirements ([[thread.req.lockable.req]](thread.req.lockable.req "32.2.5.3Cpp17Lockable requirements"))[.](#cons-5.sentence-1)
[6](#cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8471)
*Effects*: Calls m.try_lock()[.](#cons-6.sentence-1)
[7](#cons-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8475)
*Postconditions*: pm == addressof(m) and owns == res,
where res is the value returned by the call to m.try_lock()[.](#cons-7.sentence-1)
[🔗](#lib:unique_lock,constructor____)
`unique_lock(mutex_type& m, adopt_lock_t);
`
[8](#cons-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8487)
*Preconditions*: The calling thread holds a non-shared lock on m[.](#cons-8.sentence-1)
[9](#cons-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8491)
*Postconditions*: pm == addressof(m) and owns == true[.](#cons-9.sentence-1)
[10](#cons-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8495)
*Throws*: Nothing[.](#cons-10.sentence-1)
[🔗](#lib:unique_lock,constructor_____)
`template<class Clock, class Duration>
unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
`
[11](#cons-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8507)
*Preconditions*: The supplied Mutex type meets the[*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4Cpp17TimedLockable requirements[thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4Cpp17TimedLockable requirements"))[.](#cons-11.sentence-1)
[12](#cons-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8512)
*Effects*: Calls m.try_lock_until(abs_time)[.](#cons-12.sentence-1)
[13](#cons-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8516)
*Postconditions*: pm == addressof(m) and owns == res,
where res is
the value returned by the call to m.try_lock_until(abs_time)[.](#cons-13.sentence-1)
[🔗](#lib:unique_lock,constructor______)
`template<class Rep, class Period>
unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
`
[14](#cons-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8530)
*Preconditions*: The supplied Mutex type meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4Cpp17TimedLockable requirements[thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4Cpp17TimedLockable requirements"))[.](#cons-14.sentence-1)
[15](#cons-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8534)
*Effects*: Calls m.try_lock_for(rel_time)[.](#cons-15.sentence-1)
[16](#cons-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8538)
*Postconditions*: pm == addressof(m) and owns == res,
where res is the value returned by the call to m.try_lock_for(rel_time)[.](#cons-16.sentence-1)
[🔗](#lib:unique_lock,constructor_______)
`unique_lock(unique_lock&& u) noexcept;
`
[17](#cons-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8550)
*Postconditions*: pm == u_p.pm and owns == u_p.owns (where u_p is the state of u just prior to this construction), u.pm == 0 and u.owns == false[.](#cons-17.sentence-1)
[🔗](#lib:operator=,unique_lock)
`unique_lock& operator=(unique_lock&& u) noexcept;
`
[18](#cons-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8561)
*Effects*: Equivalent to: unique_lock(std::move(u)).swap(*this)
[19](#cons-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8565)
*Returns*: *this[.](#cons-19.sentence-1)
[🔗](#lib:unique_lock,destructor)
`~unique_lock();
`
[20](#cons-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8576)
*Effects*: If owns calls pm->unlock()[.](#cons-20.sentence-1)
#### [32.6.5.4.3](#locking) Locking [[thread.lock.unique.locking]](thread.lock.unique.locking)
[🔗](#lib:lock,unique_lock)
`void lock();
`
[1](#locking-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8589)
*Effects*: As if by pm->lock()[.](#locking-1.sentence-1)
[2](#locking-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8593)
*Postconditions*: owns == true[.](#locking-2.sentence-1)
[3](#locking-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8597)
*Throws*: Any exception thrown by pm->lock()[.](#locking-3.sentence-1)
system_error when an exception
is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#locking-3.sentence-2)
[4](#locking-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8602)
*Error conditions*:
- [(4.1)](#locking-4.1)
operation_not_permitted — if pm is nullptr[.](#locking-4.1.sentence-1)
- [(4.2)](#locking-4.2)
resource_deadlock_would_occur — if on entry owns is true[.](#locking-4.2.sentence-1)
[🔗](#lib:try_lock,unique_lock)
`bool try_lock();
`
[5](#locking-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8617)
*Preconditions*: The supplied Mutex meets the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3Cpp17Lockable requirements[thread.req.lockable.req]") requirements ([[thread.req.lockable.req]](thread.req.lockable.req "32.2.5.3Cpp17Lockable requirements"))[.](#locking-5.sentence-1)
[6](#locking-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8622)
*Effects*: As if by pm->try_lock()[.](#locking-6.sentence-1)
[7](#locking-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8626)
*Postconditions*: owns == res, where res is the value returned bypm->try_lock()[.](#locking-7.sentence-1)
[8](#locking-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8631)
*Returns*: The value returned by pm->try_lock()[.](#locking-8.sentence-1)
[9](#locking-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8635)
*Throws*: Any exception thrown by pm->try_lock()[.](#locking-9.sentence-1)
system_error when an exception
is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#locking-9.sentence-2)
[10](#locking-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8640)
*Error conditions*:
- [(10.1)](#locking-10.1)
operation_not_permitted — if pm is nullptr[.](#locking-10.1.sentence-1)
- [(10.2)](#locking-10.2)
resource_deadlock_would_occur — if on entry owns is true[.](#locking-10.2.sentence-1)
[🔗](#lib:try_lock_until,unique_lock)
`template<class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
`
[11](#locking-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8656)
*Preconditions*: The supplied Mutex type meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4Cpp17TimedLockable requirements[thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4Cpp17TimedLockable requirements"))[.](#locking-11.sentence-1)
[12](#locking-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8661)
*Effects*: As if by pm->try_lock_until(abs_time)[.](#locking-12.sentence-1)
[13](#locking-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8665)
*Postconditions*: owns == res, where res is the value returned bypm->try_lock_until(abs_time)[.](#locking-13.sentence-1)
[14](#locking-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8670)
*Returns*: The value returned by pm->try_lock_until(abs_time)[.](#locking-14.sentence-1)
[15](#locking-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8674)
*Throws*: Any exception thrown by pm->try_lock_until(abstime)[.](#locking-15.sentence-1)
system_error when an
exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#locking-15.sentence-2)
[16](#locking-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8679)
*Error conditions*:
- [(16.1)](#locking-16.1)
operation_not_permitted — if pm is nullptr[.](#locking-16.1.sentence-1)
- [(16.2)](#locking-16.2)
resource_deadlock_would_occur — if on entry owns istrue[.](#locking-16.2.sentence-1)
[🔗](#lib:try_lock_for,unique_lock)
`template<class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
`
[17](#locking-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8695)
*Preconditions*: The supplied Mutex type meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4Cpp17TimedLockable requirements[thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4Cpp17TimedLockable requirements"))[.](#locking-17.sentence-1)
[18](#locking-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8699)
*Effects*: As if by pm->try_lock_for(rel_time)[.](#locking-18.sentence-1)
[19](#locking-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8703)
*Postconditions*: owns == res, where res is the value returned by pm->try_lock_for(rel_time)[.](#locking-19.sentence-1)
[20](#locking-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8707)
*Returns*: The value returned by pm->try_lock_for(rel_time)[.](#locking-20.sentence-1)
[21](#locking-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8711)
*Throws*: Any exception thrown by pm->try_lock_for(rel_time)[.](#locking-21.sentence-1)
system_error when an
exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#locking-21.sentence-2)
[22](#locking-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8716)
*Error conditions*:
- [(22.1)](#locking-22.1)
operation_not_permitted — if pm is nullptr[.](#locking-22.1.sentence-1)
- [(22.2)](#locking-22.2)
resource_deadlock_would_occur — if on entry owns istrue[.](#locking-22.2.sentence-1)
[🔗](#lib:unlock,unique_lock)
`void unlock();
`
[23](#locking-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8731)
*Effects*: As if by pm->unlock()[.](#locking-23.sentence-1)
[24](#locking-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8735)
*Postconditions*: owns == false[.](#locking-24.sentence-1)
[25](#locking-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8739)
*Throws*: system_error when
an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#locking-25.sentence-1)
[26](#locking-26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8744)
*Error conditions*:
- [(26.1)](#locking-26.1)
operation_not_permitted — if on entry owns is false[.](#locking-26.sentence-1)
#### [32.6.5.4.4](#mod) Modifiers [[thread.lock.unique.mod]](thread.lock.unique.mod)
[🔗](#lib:swap,unique_lock)
`void swap(unique_lock& u) noexcept;
`
[1](#mod-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8759)
*Effects*: Swaps the data members of *this and u[.](#mod-1.sentence-1)
[🔗](#lib:release,unique_lock)
`mutex_type* release() noexcept;
`
[2](#mod-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8770)
*Postconditions*: pm == 0 and owns == false[.](#mod-2.sentence-1)
[3](#mod-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8774)
*Returns*: The previous value of pm[.](#mod-3.sentence-1)
[🔗](#lib:swap,unique_lock_)
`template<class Mutex>
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
`
[4](#mod-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8786)
*Effects*: As if by x.swap(y)[.](#mod-4.sentence-1)
#### [32.6.5.4.5](#obs) Observers [[thread.lock.unique.obs]](thread.lock.unique.obs)
[🔗](#lib:owns_lock,unique_lock)
`bool owns_lock() const noexcept;
`
[1](#obs-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8799)
*Returns*: owns[.](#obs-1.sentence-1)
[🔗](#lib:operator_bool,unique_lock)
`explicit operator bool() const noexcept;
`
[2](#obs-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8810)
*Returns*: owns[.](#obs-2.sentence-1)
[🔗](#lib:mutex,unique_lock)
`mutex_type *mutex() const noexcept;
`
[3](#obs-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8821)
*Returns*: pm[.](#obs-3.sentence-1)

View File

@@ -0,0 +1,187 @@
[thread.lock.unique.cons]
# 32 Concurrency support library [[thread]](./#thread)
## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.unique.cons)
### 32.6.5 Locks [[thread.lock]](thread.lock#unique.cons)
#### 32.6.5.4 Class template unique_lock [[thread.lock.unique]](thread.lock.unique#cons)
#### 32.6.5.4.2 Constructors, destructor, and assignment [thread.lock.unique.cons]
[🔗](#lib:unique_lock,constructor)
`unique_lock() noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8429)
*Postconditions*: pm == nullptr and owns == false[.](#1.sentence-1)
[🔗](#lib:unique_lock,constructor_)
`explicit unique_lock(mutex_type& m);
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8440)
*Effects*: Calls m.lock()[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8444)
*Postconditions*: pm == addressof(m) and owns == true[.](#3.sentence-1)
[🔗](#lib:unique_lock,constructor__)
`unique_lock(mutex_type& m, defer_lock_t) noexcept;
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8455)
*Postconditions*: pm == addressof(m) and owns == false[.](#4.sentence-1)
[🔗](#lib:unique_lock,constructor___)
`unique_lock(mutex_type& m, try_to_lock_t);
`
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8466)
*Preconditions*: The supplied Mutex type meets the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3Cpp17Lockable requirements[thread.req.lockable.req]") requirements ([[thread.req.lockable.req]](thread.req.lockable.req "32.2.5.3Cpp17Lockable requirements"))[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8471)
*Effects*: Calls m.try_lock()[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8475)
*Postconditions*: pm == addressof(m) and owns == res,
where res is the value returned by the call to m.try_lock()[.](#7.sentence-1)
[🔗](#lib:unique_lock,constructor____)
`unique_lock(mutex_type& m, adopt_lock_t);
`
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8487)
*Preconditions*: The calling thread holds a non-shared lock on m[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8491)
*Postconditions*: pm == addressof(m) and owns == true[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8495)
*Throws*: Nothing[.](#10.sentence-1)
[🔗](#lib:unique_lock,constructor_____)
`template<class Clock, class Duration>
unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
`
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8507)
*Preconditions*: The supplied Mutex type meets the[*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4Cpp17TimedLockable requirements[thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4Cpp17TimedLockable requirements"))[.](#11.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8512)
*Effects*: Calls m.try_lock_until(abs_time)[.](#12.sentence-1)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8516)
*Postconditions*: pm == addressof(m) and owns == res,
where res is
the value returned by the call to m.try_lock_until(abs_time)[.](#13.sentence-1)
[🔗](#lib:unique_lock,constructor______)
`template<class Rep, class Period>
unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
`
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8530)
*Preconditions*: The supplied Mutex type meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4Cpp17TimedLockable requirements[thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4Cpp17TimedLockable requirements"))[.](#14.sentence-1)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8534)
*Effects*: Calls m.try_lock_for(rel_time)[.](#15.sentence-1)
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8538)
*Postconditions*: pm == addressof(m) and owns == res,
where res is the value returned by the call to m.try_lock_for(rel_time)[.](#16.sentence-1)
[🔗](#lib:unique_lock,constructor_______)
`unique_lock(unique_lock&& u) noexcept;
`
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8550)
*Postconditions*: pm == u_p.pm and owns == u_p.owns (where u_p is the state of u just prior to this construction), u.pm == 0 and u.owns == false[.](#17.sentence-1)
[🔗](#lib:operator=,unique_lock)
`unique_lock& operator=(unique_lock&& u) noexcept;
`
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8561)
*Effects*: Equivalent to: unique_lock(std::move(u)).swap(*this)
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8565)
*Returns*: *this[.](#19.sentence-1)
[🔗](#lib:unique_lock,destructor)
`~unique_lock();
`
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8576)
*Effects*: If owns calls pm->unlock()[.](#20.sentence-1)

View File

@@ -0,0 +1,59 @@
[thread.lock.unique.general]
# 32 Concurrency support library [[thread]](./#thread)
## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.unique.general)
### 32.6.5 Locks [[thread.lock]](thread.lock#unique.general)
#### 32.6.5.4 Class template unique_lock [[thread.lock.unique]](thread.lock.unique#general)
#### 32.6.5.4.1 General [thread.lock.unique.general]
[🔗](#lib:unique_lock)
namespace std {template<class Mutex>class unique_lock {public:using mutex_type = Mutex; // [[thread.lock.unique.cons]](thread.lock.unique.cons "32.6.5.4.2Constructors, destructor, and assignment"), construct/copy/destroy unique_lock() noexcept; explicit unique_lock(mutex_type& m);
unique_lock(mutex_type& m, defer_lock_t) noexcept;
unique_lock(mutex_type& m, try_to_lock_t);
unique_lock(mutex_type& m, adopt_lock_t); template<class Clock, class Duration> unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time); template<class Rep, class Period> unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time); ~unique_lock();
unique_lock(const unique_lock&) = delete;
unique_lock& operator=(const unique_lock&) = delete;
unique_lock(unique_lock&& u) noexcept;
unique_lock& operator=(unique_lock&& u) noexcept; // [[thread.lock.unique.locking]](thread.lock.unique.locking "32.6.5.4.3Locking"), lockingvoid lock(); bool try_lock(); template<class Rep, class Period>bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); template<class Clock, class Duration>bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); void unlock(); // [[thread.lock.unique.mod]](thread.lock.unique.mod "32.6.5.4.4Modifiers"), modifiersvoid swap(unique_lock& u) noexcept;
mutex_type* release() noexcept; // [[thread.lock.unique.obs]](thread.lock.unique.obs "32.6.5.4.5Observers"), observersbool owns_lock() const noexcept; explicit operator bool() const noexcept;
mutex_type* mutex() const noexcept; private: mutex_type* pm; // *exposition only*bool owns; // *exposition only*};}
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8399)
An object of type unique_lock controls the ownership of a lockable
object within a scope[.](#1.sentence-1)
Ownership of the lockable object may be acquired at
construction or after construction, and may be transferred, after
acquisition, to another unique_lock object[.](#1.sentence-2)
Objects of type unique_lock are not
copyable but are movable[.](#1.sentence-3)
The behavior of a program is undefined if the contained pointerpm is not null and the lockable object pointed
to by pm does not exist for the entire remaining
lifetime ([[basic.life]](basic.life "6.8.4Lifetime")) of the unique_lock object[.](#1.sentence-4)
The suppliedMutex type shall meet the [*Cpp17BasicLockable*](thread.req.lockable.basic#:Cpp17BasicLockable "32.2.5.2Cpp17BasicLockable requirements[thread.req.lockable.basic]") requirements ([[thread.req.lockable.basic]](thread.req.lockable.basic "32.2.5.2Cpp17BasicLockable requirements"))[.](#1.sentence-5)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8411)
[*Note [1](#note-1)*:
unique_lock<Mutex> meets the [*Cpp17BasicLockable*](thread.req.lockable.basic#:Cpp17BasicLockable "32.2.5.2Cpp17BasicLockable requirements[thread.req.lockable.basic]") requirements[.](#2.sentence-1)
If Mutex meets the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3Cpp17Lockable requirements[thread.req.lockable.req]") requirements ([[thread.req.lockable.req]](thread.req.lockable.req "32.2.5.3Cpp17Lockable requirements")),unique_lock<Mutex> also meets the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3Cpp17Lockable requirements[thread.req.lockable.req]") requirements;
if Mutex meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4Cpp17TimedLockable requirements[thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4Cpp17TimedLockable requirements")),unique_lock<Mutex> also meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4Cpp17TimedLockable requirements[thread.req.lockable.timed]") requirements[.](#2.sentence-2)
— *end note*]

View File

@@ -0,0 +1,243 @@
[thread.lock.unique.locking]
# 32 Concurrency support library [[thread]](./#thread)
## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.unique.locking)
### 32.6.5 Locks [[thread.lock]](thread.lock#unique.locking)
#### 32.6.5.4 Class template unique_lock [[thread.lock.unique]](thread.lock.unique#locking)
#### 32.6.5.4.3 Locking [thread.lock.unique.locking]
[🔗](#lib:lock,unique_lock)
`void lock();
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8589)
*Effects*: As if by pm->lock()[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8593)
*Postconditions*: owns == true[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8597)
*Throws*: Any exception thrown by pm->lock()[.](#3.sentence-1)
system_error when an exception
is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#3.sentence-2)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8602)
*Error conditions*:
- [(4.1)](#4.1)
operation_not_permitted — if pm is nullptr[.](#4.1.sentence-1)
- [(4.2)](#4.2)
resource_deadlock_would_occur — if on entry owns is true[.](#4.2.sentence-1)
[🔗](#lib:try_lock,unique_lock)
`bool try_lock();
`
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8617)
*Preconditions*: The supplied Mutex meets the [*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3Cpp17Lockable requirements[thread.req.lockable.req]") requirements ([[thread.req.lockable.req]](thread.req.lockable.req "32.2.5.3Cpp17Lockable requirements"))[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8622)
*Effects*: As if by pm->try_lock()[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8626)
*Postconditions*: owns == res, where res is the value returned bypm->try_lock()[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8631)
*Returns*: The value returned by pm->try_lock()[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8635)
*Throws*: Any exception thrown by pm->try_lock()[.](#9.sentence-1)
system_error when an exception
is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#9.sentence-2)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8640)
*Error conditions*:
- [(10.1)](#10.1)
operation_not_permitted — if pm is nullptr[.](#10.1.sentence-1)
- [(10.2)](#10.2)
resource_deadlock_would_occur — if on entry owns is true[.](#10.2.sentence-1)
[🔗](#lib:try_lock_until,unique_lock)
`template<class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
`
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8656)
*Preconditions*: The supplied Mutex type meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4Cpp17TimedLockable requirements[thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4Cpp17TimedLockable requirements"))[.](#11.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8661)
*Effects*: As if by pm->try_lock_until(abs_time)[.](#12.sentence-1)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8665)
*Postconditions*: owns == res, where res is the value returned bypm->try_lock_until(abs_time)[.](#13.sentence-1)
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8670)
*Returns*: The value returned by pm->try_lock_until(abs_time)[.](#14.sentence-1)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8674)
*Throws*: Any exception thrown by pm->try_lock_until(abstime)[.](#15.sentence-1)
system_error when an
exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#15.sentence-2)
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8679)
*Error conditions*:
- [(16.1)](#16.1)
operation_not_permitted — if pm is nullptr[.](#16.1.sentence-1)
- [(16.2)](#16.2)
resource_deadlock_would_occur — if on entry owns istrue[.](#16.2.sentence-1)
[🔗](#lib:try_lock_for,unique_lock)
`template<class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
`
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8695)
*Preconditions*: The supplied Mutex type meets the [*Cpp17TimedLockable*](thread.req.lockable.timed#:Cpp17TimedLockable "32.2.5.4Cpp17TimedLockable requirements[thread.req.lockable.timed]") requirements ([[thread.req.lockable.timed]](thread.req.lockable.timed "32.2.5.4Cpp17TimedLockable requirements"))[.](#17.sentence-1)
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8699)
*Effects*: As if by pm->try_lock_for(rel_time)[.](#18.sentence-1)
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8703)
*Postconditions*: owns == res, where res is the value returned by pm->try_lock_for(rel_time)[.](#19.sentence-1)
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8707)
*Returns*: The value returned by pm->try_lock_for(rel_time)[.](#20.sentence-1)
[21](#21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8711)
*Throws*: Any exception thrown by pm->try_lock_for(rel_time)[.](#21.sentence-1)
system_error when an
exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#21.sentence-2)
[22](#22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8716)
*Error conditions*:
- [(22.1)](#22.1)
operation_not_permitted — if pm is nullptr[.](#22.1.sentence-1)
- [(22.2)](#22.2)
resource_deadlock_would_occur — if on entry owns istrue[.](#22.2.sentence-1)
[🔗](#lib:unlock,unique_lock)
`void unlock();
`
[23](#23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8731)
*Effects*: As if by pm->unlock()[.](#23.sentence-1)
[24](#24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8735)
*Postconditions*: owns == false[.](#24.sentence-1)
[25](#25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8739)
*Throws*: system_error when
an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#25.sentence-1)
[26](#26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8744)
*Error conditions*:
- [(26.1)](#26.1)
operation_not_permitted — if on entry owns is false[.](#26.sentence-1)

View File

@@ -0,0 +1,51 @@
[thread.lock.unique.mod]
# 32 Concurrency support library [[thread]](./#thread)
## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.unique.mod)
### 32.6.5 Locks [[thread.lock]](thread.lock#unique.mod)
#### 32.6.5.4 Class template unique_lock [[thread.lock.unique]](thread.lock.unique#mod)
#### 32.6.5.4.4 Modifiers [thread.lock.unique.mod]
[🔗](#lib:swap,unique_lock)
`void swap(unique_lock& u) noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8759)
*Effects*: Swaps the data members of *this and u[.](#1.sentence-1)
[🔗](#lib:release,unique_lock)
`mutex_type* release() noexcept;
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8770)
*Postconditions*: pm == 0 and owns == false[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8774)
*Returns*: The previous value of pm[.](#3.sentence-1)
[🔗](#lib:swap,unique_lock_)
`template<class Mutex>
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8786)
*Effects*: As if by x.swap(y)[.](#4.sentence-1)

View File

@@ -0,0 +1,44 @@
[thread.lock.unique.obs]
# 32 Concurrency support library [[thread]](./#thread)
## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.lock.unique.obs)
### 32.6.5 Locks [[thread.lock]](thread.lock#unique.obs)
#### 32.6.5.4 Class template unique_lock [[thread.lock.unique]](thread.lock.unique#obs)
#### 32.6.5.4.5 Observers [thread.lock.unique.obs]
[🔗](#lib:owns_lock,unique_lock)
`bool owns_lock() const noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8799)
*Returns*: owns[.](#1.sentence-1)
[🔗](#lib:operator_bool,unique_lock)
`explicit operator bool() const noexcept;
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8810)
*Returns*: owns[.](#2.sentence-1)
[🔗](#lib:mutex,unique_lock)
`mutex_type *mutex() const noexcept;
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L8821)
*Returns*: pm[.](#3.sentence-1)