This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Resolved status.
Section: 32.6 [thread.mutex] Status: Resolved Submitter: Anthony Williams Opened: 2009-11-17 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [thread.mutex].
View all issues with Resolved status.
Discussion:
The Mutex requirements in 32.6.4 [thread.mutex.requirements] and
32.6.4.3 [thread.timedmutex.requirements] confuse the requirements on the
behaviour of std::mutex et al with the requirements on
Lockable types for use with std::unique_lock,
std::lock_guard and std::condition_variable_any.
[ 2010 Pittsburgh: ]
Concepts of threads chapter and issue presentation are: Lockable < Mutex < TimedMutex and Lockable < TimedLockable < TimedMutex.
Typo in failed deletion of Mutex in 30.4.4 p4 edits.
Lockable requirements are too weak for condition_variable_any, but the Mutex requirements are too strong.
Need subset of Lockable requirements for condition_variable_any that does not include try_lock. E.g. CvLockable < Lockable.
Text needs updating to recent draft changes.
Needs to specify exception behavior in Lockable.
The current standard is fine for what it says, but it places requirements that are too strong on authors of mutexes and locks.
Move to open status. Suggest Anthony look at condition_variable_any requirements. Suggest Anthony refine requirements/concepts categories.
[ 2010-03-28 Daniel synced with N3092. ]
[ 2010-10-25 Daniel adds: ]
Accepting n3130 would solve this issue.
[ 2010-11 Batavia: ]
Resolved by adopting n3197.
Proposed resolution:
Add a new section to 32.2 [thread.req] after 32.2.4 [thread.req.timing] as follows:
30.2.5 Requirements for Lockable types
The standard library templates
unique_lock(32.6.5.4 [thread.lock.unique]),lock_guard(32.6.5.2 [thread.lock.guard]),lock,try_lock(32.6.6 [thread.lock.algorithm]) andcondition_variable_any(32.7.5 [thread.condition.condvarany]) all operate on user-suppliedLockableobjects. Such an object must support the member functions specified for either theLockableRequirements or theTimedLockablerequirements as appropriate to acquire or release ownership of alockby a giventhread. [Note: the nature of any lock ownership and any synchronization it may entail are not part of these requirements. — end note]30.2.5.1 Lockable Requirements
In order to qualify as a
Lockabletype, the following expressions must be supported, with the specified semantics, wheremdenotes a value of typeLthat supports theLockable:The expression
m.lock()shall be well-formed and have the following semantics:
- Effects:
- Block until a lock can be acquired for the current thread.
- Return type:
voidThe expression
m.try_lock()shall be well-formed and have the following semantics:
- Effects:
- Attempt to acquire a lock for the current thread without blocking.
- Return type:
bool- Returns:
trueif the lock was acquired,falseotherwise.The expression
m.unlock()shall be well-formed and have the following semantics:
- Effects:
- Release a lock on
mheld by the current thread.- Return type:
void- Throws:
- Nothing if the current thread holds a lock on
m.30.2.5.2
TimedLockableRequirementsFor a type to qualify as
TimedLockableit must meet theLockablerequirements, and additionally the following expressions must be well-formed, with the specified semantics, wheremis an instance of a typeTLthat supports theTimedLockablerequirements,rel_timedenotes instantiation ofduration(30.5 [time.duration]) andabs_timedenotes an instantiation oftime_point(30.6 [time.point])The expression
m.try_lock_for(rel_time)shall be well-formed and have the following semantics:
- Effects:
- Attempt to acquire a lock for the current thread within the specified time period.
- Return type:
bool- Returns:
trueif the lock was acquired,falseotherwise.The expression
m.try_lock_until(abs_time)shall be well-formed and have the following semantics:
- Effects:
- Attempt to acquire a lock for the current thread before the specified point in time.
- Return type:
bool- Returns:
trueif the lock was acquired,falseotherwise.
Replace 32.6.4 [thread.mutex.requirements] paragraph 2 with the following:
2 This section describes requirements on
template argument types used to instantiate templates defined inthe mutex types supplied by the C++ standard library.The template definitions in the C++ standard library referThese types shall conform to the namedMutexrequirements whose details are set out below. In this description,mis an object ofaone of the standard library mutex typesMutextypestd::mutex,std::recursive_mutex,std::timed_mutexorstd::recursive_timed_mutex..
Add the following paragraph after 32.6.4 [thread.mutex.requirements] paragraph 2:
A
Mutextype shall conform to theLockablerequirements (30.2.5.1).
Replace 32.6.4.3 [thread.timedmutex.requirements] paragraph 1 with the following:
The C++ standard library
TimedMutextypesstd::timed_mutexandstd::recursive_timed_mutexAshall meet the requirements for aTimedMutextypeMutextype. In addition,itthey shall meet the requirements set outin this Clause 30.4.2below, whererel_timedenotes an instantiation ofduration(30.5 [time.duration]) andabs_timedenotes an instantiation oftime_point(30.6 [time.point]).
Add the following paragraph after 32.6.4.3 [thread.timedmutex.requirements] paragraph 1:
A
TimedMutextype shall conform to theTimedLockablerequirements (30.2.5.1).
Add the following paragraph following 32.6.5.2 [thread.lock.guard] paragraph 1:
The supplied
Mutextype shall meet theLockablerequirements (30.2.5.1).
Add the following paragraph following 32.6.5.4 [thread.lock.unique] paragraph 1:
The supplied
Mutextype shall meet theLockablerequirements (30.2.5.1).unique_lock<Mutex>meets theLockablerequirements. IfMutexmeets theTimedLockablerequirements (30.2.5.2) thenunique_lock<Mutex>also meets theTimedLockablerequirements.
Replace the use of "mutex" or "mutex object" with "lockable object" throughout clause 32.6.5 [thread.lock] paragraph 1:
1 A lock is an object that holds a reference to a
mutexlockable object and may unlock themutexlockable object during the lock's destruction (such as when leaving block scope). A thread of execution may use a lock to aid in managingmutexownership of a lockable object in an exception safe manner. A lock is said to own amutexlockable object if it is currently managing the ownership of thatmutexlockable object for a thread of execution. A lock does not manage the lifetime of themutexlockable object it references. [ Note: Locks are intended to ease the burden of unlocking themutexlockable object under both normal and exceptional circumstances. — end note ]
32.6.5 [thread.lock] paragaph 2:
2 Some lock constructors take tag types which describe what should be done with the
mutexlockable object during the lock's constuction.
32.6.5.2 [thread.lock.guard] paragaph 1:
1 An object of type
lock_guardcontrols the ownership of amutexlockable object within a scope. Alock_guardobject maintains ownership of amutexlockable object throughout thelock_guardobject's lifetime. The behavior of a program is undefined if themutexlockable object referenced bypmdoes not exist for the entire lifetime (3.8) of thelock_guardobject.Mutexshall meet theLockablerequirements (30.2.5.1).
32.6.5.4 [thread.lock.unique] paragaph 1:
1 An object of type
unique_lockcontrols the ownership of amutexlockable object within a scope.MutexoOwnership of the lockable object may be acquired at construction or after construction, and may be transferred, after acquisition, to anotherunique_lockobject. Objects of typeunique_lockare not copyable but are movable. The behavior of a program is undefined if the contained pointerpmis not null and the mutex pointed to bypmdoes not exist for the entire remaining lifetime (3.8) of theunique_lockobject.Mutexshall meet theLockablerequirements (30.2.5.1).
Add the following to the precondition of unique_lock(mutex_type&
m, const chrono::time_point<Clock, Duration>& abs_time) in
32.6.5.4.2 [thread.lock.unique.cons] paragraph 18:
template <class Clock, class Duration> unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);18 Requires: If
mutex_typeis not a recursive mutex the calling thread does not own the mutex. The suppliedmutex_typetype shall meet theTimedLockablerequirements (30.2.5.2).
Add the following to the precondition of unique_lock(mutex_type&
m,
const chrono::duration<Rep, Period>& rel_time) in
32.6.5.4.2 [thread.lock.unique.cons]
paragraph 22
22 Requires: If
mutex_typeis not a recursive mutex the calling thread does not own the mutex. The suppliedmutex_typetype shall meet theTimedLockablerequirements (30.2.5.2).
Add the following as a precondition of bool try_lock_until(const
chrono::time_point<Clock, Duration>& abs_time) before
32.6.5.4.3 [thread.lock.unique.locking] paragraph 8
template <class Clock, class Duration> bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);Requires: The supplied
mutex_typetype shall meet theTimedLockablerequirements (30.2.5.2).
Add the following as a precondition of bool try_lock_for(const
chrono::duration<Rep, Period>& rel_time) before
32.6.5.4.3 [thread.lock.unique.locking] paragraph 12
template <class Rep, class Period> bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);Requires: The supplied
mutex_typetype shall meet theTimedLockablerequirements (30.2.5.2).
Replace 32.6.6 [thread.lock.algorithm] p1 with the following:
template <class L1, class L2, class... L3> int try_lock(L1&, L2&, L3&...);1 Requires: Each template parameter type shall meet the
requirements (30.2.5.1).MutexLockable, except that a call to[Note: Thetry_lock()may throw an exception.unique_lockclass template meets these requirements when suitably instantiated. — end note]
Replace 32.6.6 [thread.lock.algorithm] p4 with the following:
template <class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);4 Requires: Each template parameter type shall meet the
Mutexrequirements (30.2.5.1).MutexLockable, except that a call to[Note: Thetry_lock()may throw an exception.unique_lockclass template meets these requirements when suitably instantiated. — end note]
Replace 32.7.5 [thread.condition.condvarany] paragraph 1 with:
1 A
Locktype shall meet therequirements for aMutextypeLockablerequirements (30.2.5.1), except thattry_lockis not required. [Note: All of the standard mutex types meet this requirement. — end note]