diff --git a/source/threads.tex b/source/threads.tex index 1ca01ecfca..bedc47bae5 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -187,13 +187,37 @@ \tcode{try_lock}\iref{thread.lock.algorithm}, and \tcode{condition_variable_any}\iref{thread.condition.condvarany} all operate on user-supplied lockable objects. The \oldconcept{BasicLockable} requirements, the \oldconcept{Lockable} requirements, -and the \oldconcept{TimedLockable} requirements list the requirements imposed by these library types +the \oldconcept{TimedLockable} requirements, +the \oldconcept{SharedLockable} requirements, and +the \oldconcept{SharedTimedLock\-able} requirements +list the requirements imposed by these library types in order to acquire or release ownership of a \tcode{lock} by a given execution agent. \begin{note} The nature of any lock ownership and any synchronization it entails are not part of these requirements. \end{note} +\pnum +A lock on an object \tcode{m} is said to be +\begin{itemize} +\item +a \defnadj{non-shared}{lock} if it is acquired by a call to +\tcode{lock}, +\tcode{try_lock}, +\tcode{try_lock_for}, or +\tcode{try_lock_until} on \tcode{m}, or +\item +a \defnadj{shared}{lock} if it is acquired by a call to +\tcode{lock_shared}, +\tcode{try_lock_shared}, +\tcode{try_lock_shared_for}, or +\tcode{try_lock_shared_until} on \tcode{m}. +\end{itemize} +\begin{note} +Only the method of lock acquisition is considered; +the nature of any lock ownership is not part of these definitions. +\end{note} + \rSec3[thread.req.lockable.basic]{\oldconcept{BasicLockable} requirements} \pnum @@ -219,11 +243,11 @@ \begin{itemdescr} \pnum \expects -The current execution agent holds a lock on \tcode{m}. +The current execution agent holds a non-shared lock on \tcode{m}. \pnum \effects -Releases a lock on \tcode{m} held by the current execution agent. +Releases a non-shared lock on \tcode{m} held by the current execution agent. \pnum \throws @@ -306,6 +330,109 @@ \tcode{true} if the lock was acquired, otherwise \tcode{false}. \end{itemdescr} +\rSec3[thread.req.lockable.shared]{\oldconcept{SharedLockable} requirements} + +\pnum +A type \tcode{L} meets the \oldconcept{SharedLockable} requirements if +the following expressions are well-formed, have the specified semantics, and +the expression \tcode{m.try_lock_shared()} has type \tcode{bool} +(\tcode{m} denotes a value of type \tcode{L}): + +\begin{itemdecl} +m.lock_shared() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Blocks until a lock can be acquired for the current execution agent. +If an exception is thrown then a lock shall not have been acquired for +the current execution agent. +\end{itemdescr} + +\begin{itemdecl} +m.try_lock_shared() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Attempts to acquire a lock for the current execution agent without blocking. +If an exception is thrown then a lock shall not have been acquired for +the current execution agent. + +\pnum +\returns +\tcode{true} if the lock was acquired, \tcode{false} otherwise. +\end{itemdescr} + +\begin{itemdecl} +m.unlock_shared() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +The current execution agent holds a shared lock on \tcode{m}. + +\pnum +\effects +Releases a shared lock on \tcode{m} held by the current execution agent. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\rSec3[thread.req.lockable.shared.timed]{\oldconcept{SharedTimedLockable} requirements} + +\pnum +A type \tcode{L} meets the \oldconcept{SharedTimedLockable} requirements if +it meets the \oldconcept{SharedLockable} requirements, and +the following expressions are well-formed, have type \tcode{bool}, and +have the specified semantics +(\tcode{m} denotes a value of type \tcode{L}, +\tcode{rel_time} denotes a value of a specialization of \tcode{chrono::duration}, and +\tcode{abs_time} denotes a value of a specialization of \tcode{chrono::time_point}). + +\begin{itemdecl} +m.try_lock_shared_for(rel_time) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Attempts to acquire a lock for the current execution agent within +the relative timeout\iref{thread.req.timing} specified by \tcode{rel_time}. +The function will not return within the timeout specified by \tcode{rel_time} +unless it has obtained a lock on \tcode{m} for the current execution agent. +If an exception is thrown then a lock has not been acquired for +the current execution agent. + +\pnum +\returns +\tcode{true} if the lock was acquired, \tcode{false} otherwise. +\end{itemdescr} + +\begin{itemdecl} +m.try_lock_shared_until(abs_time) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Attempts to acquire a lock for the current execution agent before +the absolute timeout\iref{thread.req.timing} specified by \tcode{abs_time}. +The function will not return before the timeout specified by \tcode{abs_time} +unless it has obtained a lock on \tcode{m} for the current execution agent. +If an exception is thrown then a lock has not been acquired for +the current execution agent. + +\pnum +\returns +\tcode{true} if the lock was acquired, \tcode{false} otherwise. +\end{itemdescr} + \rSec1[thread.stoptoken]{Stop tokens} \rSec2[thread.stoptoken.intro]{Introduction} @@ -1982,9 +2109,9 @@ \tcode{shared_mutex}, and \tcode{shared_timed_mutex}. They meet the requirements set out in \ref{thread.mutex.requirements.mutex}. In this description, \tcode{m} denotes an object of a mutex type. - -\pnum +\begin{note} The mutex types meet the \oldconcept{Lockable} requirements\iref{thread.req.lockable.req}. +\end{note} \pnum The mutex types meet \oldconcept{DefaultConstructible} and \oldconcept{Destructible}. @@ -2258,10 +2385,10 @@ instantiation of \tcode{duration}\iref{time.duration}, and \tcode{abs_time} denotes an object of an instantiation of \tcode{time_point}\iref{time.point}. - -\pnum +\begin{note} The timed mutex types meet the \oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed}. +\end{note} \pnum The expression \tcode{m.try_lock_for(rel_time)} is well-formed @@ -2472,6 +2599,10 @@ mutex types\iref{thread.mutex.requirements.mutex} and additionally meet the requirements set out below. In this description, \tcode{m} denotes an object of a shared mutex type. +\begin{note} +The shared mutex types meet the \oldconcept{SharedLockable} +requirements\iref{thread.req.lockable.shared}. +\end{note} \pnum \indextext{block (execution)}% @@ -2648,6 +2779,10 @@ \tcode{duration}\iref{time.duration}, and \tcode{abs_time} denotes an object of an instantiation of \tcode{time_point}\iref{time.point}. +\begin{note} +The shared timed mutex types meet the \oldconcept{SharedTimedLockable} +requirements\iref{thread.req.lockable.shared.timed}. +\end{note} \pnum The expression \tcode{m.try_lock_shared_for(rel_time)} is well-formed and @@ -2866,11 +3001,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\expects -If \tcode{mutex_type} is not a recursive mutex, -the calling thread does not own the mutex \tcode{m}. - \pnum \effects Initializes \tcode{pm} with \tcode{m}. Calls \tcode{m.lock()}. @@ -2884,7 +3014,7 @@ \begin{itemdescr} \pnum \expects -The calling thread owns the mutex \tcode{m}. +The calling thread holds a non-shared lock on \tcode{m}. \pnum \effects @@ -2903,10 +3033,9 @@ \begin{itemdescr} \pnum \effects -As if by \tcode{pm.unlock()}. +Equivalent to: \tcode{pm.unlock()} \end{itemdescr} - \rSec3[thread.lock.scoped]{Class template \tcode{scoped_lock}} \indexlibraryglobal{scoped_lock}% @@ -2957,11 +3086,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\expects -If a \tcode{MutexTypes} type is not a recursive mutex, -the calling thread does not own the corresponding mutex element of \tcode{m}. - \pnum \effects Initializes \tcode{pm} with \tcode{tie(m...)}. @@ -2978,7 +3102,7 @@ \begin{itemdescr} \pnum \expects -The calling thread owns all the mutexes in \tcode{m}. +The calling thread holds a non-shared lock on each element of \tcode{m}. \pnum \effects @@ -3099,10 +3223,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\expects -If \tcode{mutex_type} is not a recursive mutex the calling thread does not own the mutex. - \pnum \effects Calls \tcode{m.lock()}. @@ -3133,7 +3253,6 @@ \expects The supplied \tcode{Mutex} type meets the \oldconcept{Lockable} requirements\iref{thread.req.lockable.req}. -If \tcode{mutex_type} is not a recursive mutex the calling thread does not own the mutex. \pnum \effects @@ -3153,7 +3272,7 @@ \begin{itemdescr} \pnum \expects -The calling thread owns the mutex. +The calling thread holds a non-shared lock on \tcode{m}. \pnum \ensures @@ -3173,8 +3292,7 @@ \begin{itemdescr} \pnum \expects -If \tcode{mutex_type} is not a recursive mutex the calling thread -does not own the mutex. The supplied \tcode{Mutex} type meets the +The supplied \tcode{Mutex} type meets the \oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed}. \pnum @@ -3197,7 +3315,6 @@ \begin{itemdescr} \pnum \expects -If \tcode{mutex_type} is not a recursive mutex the calling thread does not own the mutex. The supplied \tcode{Mutex} type meets the \oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed}. \pnum @@ -3565,12 +3682,16 @@ is undefined if the contained pointer \tcode{pm} is not null and the lockable object pointed to by \tcode{pm} does not exist for the entire remaining lifetime\iref{basic.life} of the \tcode{shared_lock} object. The supplied -\tcode{Mutex} type shall meet the shared mutex -requirements\iref{thread.sharedtimedmutex.requirements}. +\tcode{Mutex} type shall meet the \oldconcept{SharedLockable} +requirements\iref{thread.req.lockable.shared}. \pnum \begin{note} -\tcode{shared_lock} meets the \oldconcept{TimedLockable} +\tcode{shared_lock} meets the \oldconcept{Lockable} +requirements\iref{thread.req.lockable.req}. +If \tcode{Mutex} meets the \oldconcept{Shared\-TimedLockable} +requirements\iref{thread.req.lockable.shared.timed}, +\tcode{shared_lock} also meets the \oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed}. \end{note} @@ -3593,10 +3714,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\expects -The calling thread does not own the mutex for any ownership mode. - \pnum \effects Calls \tcode{m.lock_shared()}. @@ -3623,10 +3740,6 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\expects -The calling thread does not own the mutex for any ownership mode. - \pnum \effects Calls \tcode{m.try_lock_shared()}. @@ -3646,7 +3759,7 @@ \begin{itemdescr} \pnum \expects -The calling thread has shared ownership of the mutex. +The calling thread holds a shared lock on \tcode{m}. \pnum \ensures @@ -3663,7 +3776,8 @@ \begin{itemdescr} \pnum \expects -The calling thread does not own the mutex for any ownership mode. +\tcode{Mutex} meets the \oldconcept{SharedTimedLockable} +requirements\iref{thread.req.lockable.shared.timed}. \pnum \effects @@ -3686,7 +3800,8 @@ \begin{itemdescr} \pnum \expects -The calling thread does not own the mutex for any ownership mode. +\tcode{Mutex} meets the \oldconcept{SharedTimedLockable} +requirements\iref{thread.req.lockable.shared.timed}. \pnum \effects @@ -3810,6 +3925,11 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{Mutex} meets the \oldconcept{SharedTimedLockable} +requirements\iref{thread.req.lockable.shared.timed}. + \pnum \effects As if by \tcode{pm->try_lock_shared_until(abs_time)}. @@ -3845,6 +3965,11 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{Mutex} meets the \oldconcept{SharedTimedLockable} +requirements\iref{thread.req.lockable.shared.timed}. + \pnum \effects As if by \tcode{pm->try_lock_shared_for(rel_time)}.