This page is a snapshot from the LWG issues list, see theLibrary Active Issues List for more information and the meaning ofResolved status.
Section: 32.6[thread.mutex]Status:ResolvedSubmitter: Anthony WilliamsOpened: 2009-11-17Last modified: 2016-01-28
Priority:Not Prioritized
View all otherissues in [thread.mutex].
View all issues withResolved status.
Discussion:
TheMutex requirements in 32.6.4[thread.mutex.requirements] and32.6.4.3[thread.timedmutex.requirements] confuse the requirements on thebehaviour ofstd::mutex et al with the requirements onLockable types for use withstd::unique_lock,std::lock_guard andstd::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 Mutexrequirements are too strong.
Need subset of Lockable requirements for condition_variable_any that does notinclude 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 thatare too strong on authors of mutexes and locks.
Move to open status. Suggest Anthony look at condition_variable_anyrequirements. Suggest Anthony refine requirements/concepts categories.
[2010-03-28 Daniel synced with N3092.]
[2010-10-25 Daniel adds:]
Acceptingn3130 would solve this issue.
[2010-11 Batavia:]
Resolved by adoptingn3197.
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 functionsspecified for either theLockableRequirements or theTimedLockablerequirements as appropriate to acquire or releaseownership of alockby a giventhread. [Note: thenature of any lock ownership and any synchronization it may entail are not partof these requirements. —end note]30.2.5.1 Lockable Requirements
In order to qualify as a
Lockabletype, the following expressions mustbe supported, with the specified semantics, wheremdenotes a value oftypeLthat supports theLockable:The expression
m.lock()shall be well-formed and have the followingsemantics:
- 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 thefollowing 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 thefollowing 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 followingexpressions must be well-formed, with the specified semantics,wheremis an instance of a typeTLthat supportstheTimedLockablerequirements,rel_timedenotesinstantiation 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 thefollowing 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 thefollowing 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 thefollowing:
2 This section describes requirements on
template argument typesused to instantiate templates defined inthe mutex typessupplied by the C++ standard library.The templatedefinitions in the C++ standard library referThese types shallconform to the namedMutexrequirements whose details are setout below. In this description,mis an objectofaone 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 thefollowing:
The C++ standard library
TimedMutextypesstd::timed_mutexandstd::recursive_timed_mutexAshall meet the requirements foraTimedMutextypeMutextype. In addition,itthey shallmeet the requirements set outin this Clause 30.4.2below,whererel_timedenotes an instantiation ofduration(30.5[time.duration]) andabs_timedenotes an instantiationoftime_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 toa
mutexlockable object and may unlockthemutexlockable object during the lock'sdestruction (such as when leaving block scope). A thread of executionmay use a lock to aid in managingmutexownershipof alockable object in an exception safe manner. A lock is said toown amutexlockable object if it is currentlymanaging the ownership of thatmutexlockableobject for a thread of execution. A lock does not manage thelifetime of themutexlockable object itreferences. [ Note: Locks are intended to ease the burden ofunlocking themutexlockable object under bothnormal and exceptional circumstances. — end note ]
32.6.5[thread.lock] paragaph 2:
2 Some lock constructors take tag types which describe what should bedone with the
mutexlockable object during thelock'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 ofamutexlockable object throughoutthelock_guardobject's lifetime. The behavior of a programis undefined if themutexlockable objectreferenced 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 ofamutexlockable object within ascope.MutexoOwnershipof thelockable object may be acquired at construction or afterconstruction, and may be transferred, after acquisition, toanotherunique_lockobject. Objects oftypeunique_lockare not copyable but are movable. Thebehavior of a program is undefined if the containedpointerpmis not null and the mutex pointed tobypmdoes not exist for the entire remaining lifetime (3.8)of theunique_lockobject.Mutexshall meettheLockablerequirements (30.2.5.1).
Add the following to the precondition ofunique_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);18Requires: 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 ofunique_lock(mutex_type& m,const chrono::duration<Rep, Period>& rel_time) in 32.6.5.4.2[thread.lock.unique.cons]paragraph 22
22Requires: If
mutex_typeis not a recursive mutex thecalling thread does not own the mutex.The suppliedmutex_typetype shall meet theTimedLockablerequirements (30.2.5.2).
Add the following as a precondition ofbool try_lock_until(constchrono::time_point<Clock, Duration>& abs_time) before32.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 ofbool try_lock_for(constchrono::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&...);1Requires: 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&...);4Requires: 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]