<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 1268: The Mutex requirements in 30.4.1 and 30.4.2 are wrong</title>
<meta property="og:title" content="Issue 1268: The Mutex requirements in 30.4.1 and 30.4.2 are wrong">
<meta property="og:description" content="C++ library issue. Status: Resolved">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue1268.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#Resolved">Resolved</a> status.</em></p>
<h3 id="1268"><a href="lwg-defects.html#1268">1268</a>. The Mutex requirements in 30.4.1 and 30.4.2 are wrong</h3>
<p><b>Section:</b> 32.6 <a href="https://wg21.link/thread.mutex">[thread.mutex]</a> <b>Status:</b> <a href="lwg-active.html#Resolved">Resolved</a>
 <b>Submitter:</b> Anthony Williams <b>Opened:</b> 2009-11-17 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#thread.mutex">issues</a> in [thread.mutex].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Resolved">Resolved</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The <code>Mutex</code> requirements in 32.6.4 <a href="https://wg21.link/thread.mutex.requirements">[thread.mutex.requirements]</a> and
32.6.4.3 <a href="https://wg21.link/thread.timedmutex.requirements">[thread.timedmutex.requirements]</a> confuse the requirements on the
behaviour of <code>std::mutex</code> et al with the requirements on
<code>Lockable</code> types for use with <code>std::unique_lock</code>,
<code>std::lock_guard</code> and <code>std::condition_variable_any</code>.
</p>

<p><i>[
2010 Pittsburgh:
]</i></p>


<blockquote>
<p>
Concepts of threads chapter and issue presentation are: Lockable &lt; Mutex &lt;
TimedMutex and Lockable &lt; TimedLockable &lt; TimedMutex.
</p>
<p>
Typo in failed deletion of Mutex in 30.4.4 p4 edits.
</p>
<p>
Lockable requirements are too weak for condition_variable_any, but the Mutex
requirements are too strong.
</p>
<p>
Need subset of Lockable requirements for condition_variable_any that does not
include try_lock. E.g. CvLockable &lt; Lockable.
</p>
<p>
Text needs updating to recent draft changes.
</p>
<p>
Needs to specify exception behavior in Lockable.
</p>
<p>
The current standard is fine for what it says, but it places requirements that
are too strong on authors of mutexes and locks.
</p>
<p>
Move to open status. Suggest Anthony look at condition_variable_any
requirements. Suggest Anthony refine requirements/concepts categories.
</p>
<p>
Related to <a href="lwg-defects.html#964" title="Various threading bugs #14 (Status: Resolved)">964</a><sup><a href="https://cplusplus.github.io/LWG/issue964" title="Latest snapshot">(i)</a></sup> and <a href="lwg-defects.html#966" title="Various threading bugs #16 (Status: Resolved)">966</a><sup><a href="https://cplusplus.github.io/LWG/issue966" title="Latest snapshot">(i)</a></sup>
</p>
</blockquote>

<p><i>[
2010-03-28 Daniel synced with N3092.
]</i></p>


<p><i>[
2010-10-25 Daniel adds:
]</i></p>


<blockquote><p>
Accepting <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3130.html">n3130</a> 
would solve this issue.
</p></blockquote>

<p><i>[
2010-11 Batavia:
]</i></p>


<blockquote><p>
Resolved by adopting <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3197.htm">n3197</a>.
</p></blockquote>




<p id="res-1268"><b>Proposed resolution:</b></p>
<p>
Add a new section to 32.2 <a href="https://wg21.link/thread.req">[thread.req]</a> after 32.2.4 <a href="https://wg21.link/thread.req.timing">[thread.req.timing]</a> 
as follows:
</p>

<blockquote>
<p>
30.2.5 Requirements for Lockable types
</p>

<p>
The standard library templates <code>unique_lock</code> (32.6.5.4 <a href="https://wg21.link/thread.lock.unique">[thread.lock.unique]</a>), <code>lock_guard</code> (32.6.5.2 <a href="https://wg21.link/thread.lock.guard">[thread.lock.guard]</a>), <code>lock</code>, <code>try_lock</code> (32.6.6 <a href="https://wg21.link/thread.lock.algorithm">[thread.lock.algorithm]</a>) and <code>condition_variable_any</code> (32.7.5 <a href="https://wg21.link/thread.condition.condvarany">[thread.condition.condvarany]</a>) all operate on user-supplied
<code>Lockable</code> objects. Such an object must support the member functions
specified for either the <code>Lockable</code> Requirements or the
<code>TimedLockable</code> requirements as appropriate to acquire or release
ownership of a <code>lock</code> by a given <code>thread</code>. [<i>Note:</i> the
nature of any lock ownership and any synchronization it may entail are not part
of these requirements. &mdash; <i>end note</i>]
</p>

<p>
30.2.5.1  Lockable Requirements
</p>

<p>
In order to qualify as a <code>Lockable</code> type, the following expressions must
be supported, with the specified semantics, where <code>m</code> denotes a value of
type <code>L</code> that supports the <code>Lockable</code>:
</p>

<p>
The expression <code>m.lock()</code> shall be well-formed and have the following
semantics:
</p>

<dl>
  <dt>Effects:</dt><dd>Block until a lock can be acquired for the current thread.</dd>
  <dt>Return type:</dt><dd><code>void</code></dd>
</dl>

<p>
The expression <code>m.try_lock()</code> shall be well-formed and have the
following semantics:
</p>

<dl>
  <dt>Effects:</dt><dd>Attempt to acquire a lock for the current thread without blocking.</dd>
  <dt>Return type:</dt><dd><code>bool</code></dd>
  <dt>Returns:</dt><dd><code>true</code> if the lock was
  acquired, <code>false</code> otherwise.</dd>
</dl>

<p>
The expression <code>m.unlock()</code> shall be well-formed and have the
following semantics:
</p>

<dl>
  <dt>Effects:</dt><dd>Release a lock on <code>m</code> held by the current thread.</dd>
  <dt>Return type:</dt><dd><code> void</code></dd>
  <dt>Throws:</dt><dd> Nothing if the current thread holds a lock on <code>m</code>.</dd>
</dl>

<p>
30.2.5.2 <code>TimedLockable</code> Requirements
</p>

<p>
For a type to qualify as <code>TimedLockable</code> it must meet the
<code>Lockable</code> requirements, and additionally the following
expressions must be well-formed, with the specified semantics,
where <code>m</code> is an instance of a type <code>TL</code> that supports
the <code>TimedLockable</code> requirements, <code>rel_time</code> denotes
instantiation of <code>duration</code> (30.5 <a href="https://wg21.link/time.duration">[time.duration]</a>) and <code>abs_time</code>
denotes an instantiation of <code>time_point</code> (30.6 <a href="https://wg21.link/time.point">[time.point]</a>)

</p>

<p>
The expression <code>m.try_lock_for(rel_time)</code> shall be well-formed and have the
following semantics:
</p>

<dl>
  <dt>Effects:</dt><dd>Attempt to acquire a lock for the current
  thread within the specified time period.</dd>
  <dt>Return type:</dt><dd><code>bool</code></dd>
  <dt>Returns:</dt><dd><code>true</code> if the lock was
  acquired, <code>false</code> otherwise.</dd>
</dl>

<p>
The expression <code>m.try_lock_until(abs_time)</code> shall be well-formed and have the
following semantics:
</p>

<dl>
  <dt>Effects:</dt><dd>Attempt to acquire a lock for the current
  thread before the specified point in time.</dd>
  <dt>Return type:</dt><dd><code>bool</code></dd>
  <dt>Returns:</dt><dd><code>true</code> if the lock was
  acquired, <code>false</code> otherwise.</dd>
</dl>
</blockquote>

<p>
Replace 32.6.4 <a href="https://wg21.link/thread.mutex.requirements">[thread.mutex.requirements]</a> paragraph 2 with the
following:
</p>

<blockquote><p>
2 This section describes requirements on <del>template argument types
used to instantiate templates defined in</del> <ins>the mutex types
supplied by</ins> the C++ standard library. <del>The template
definitions in the C++ standard library refer</del> These types shall
conform to the named <code>Mutex</code> requirements whose details are set
out below.  In this description, <code>m</code> is an object
of <del>a <code>Mutex</code> type</del>
<ins>one of the standard library mutex types <code>std::mutex</code>,
<code>std::recursive_mutex</code>, <code>std::timed_mutex</code> or
<code>std::recursive_timed_mutex</code>.</ins>.
</p></blockquote>

<p>
Add the following paragraph after 32.6.4 <a href="https://wg21.link/thread.mutex.requirements">[thread.mutex.requirements]</a>
paragraph 2:
</p>

<blockquote><p><ins>
A <code>Mutex</code> type shall conform to the <code>Lockable</code>
requirements (30.2.5.1).
</ins></p></blockquote>

<p>
Replace 32.6.4.3 <a href="https://wg21.link/thread.timedmutex.requirements">[thread.timedmutex.requirements]</a> paragraph 1 with the
following:
</p>

<blockquote><p>
<ins>The C++ standard library <code>TimedMutex</code> types <code>std::timed_mutex</code>
  and <code>std::recursive_timed_mutex</code> </ins>
<del>A <code>TimedMutex</code> type</del> shall meet the requirements for
a <code>Mutex</code> type. In addition, <del>it</del><ins>they</ins> shall
meet the requirements set out <del>in this Clause 30.4.2</del><ins>below</ins>,
where <code>rel_time</code> denotes an instantiation of <code>duration</code>
(30.5 <a href="https://wg21.link/time.duration">[time.duration]</a>) and <code>abs_time</code> denotes an instantiation
of <code>time_point</code> (30.6 <a href="https://wg21.link/time.point">[time.point]</a>).
</p></blockquote>

<p>
Add the following paragraph after 32.6.4.3 <a href="https://wg21.link/thread.timedmutex.requirements">[thread.timedmutex.requirements]</a> paragraph 1:
</p>

<blockquote><p><ins>
A <code>TimedMutex</code> type shall conform to the <code>TimedLockable</code>
requirements (30.2.5.1).
</ins></p></blockquote>


<p>
Add the following paragraph following 32.6.5.2 <a href="https://wg21.link/thread.lock.guard">[thread.lock.guard]</a>
paragraph 1:
</p>

<blockquote><p><ins>
The supplied <code>Mutex</code> type shall meet the <code>Lockable</code> 
requirements (30.2.5.1).
</ins></p></blockquote>

<p>
Add the following paragraph following 32.6.5.4 <a href="https://wg21.link/thread.lock.unique">[thread.lock.unique]</a>
paragraph 1:
</p>

<blockquote><p><ins>
The supplied <code>Mutex</code> type shall meet the <code>Lockable</code> 
requirements
(30.2.5.1). <code>unique_lock&lt;Mutex&gt;</code> meets the <code>Lockable</code>
requirements. If <code>Mutex</code> meets the <code>TimedLockable</code> 
requirements
(30.2.5.2) then <code>unique_lock&lt;Mutex&gt;</code> also meets the
<code>TimedLockable</code> requirements.
</ins></p></blockquote>

<p>
Replace the use of "mutex" or "mutex object" with "lockable object"
throughout clause 32.6.5 <a href="https://wg21.link/thread.lock">[thread.lock]</a> paragraph 1:
</p>

<blockquote><p>
1 A lock is an object that holds a reference to
a <del>mutex</del><ins>lockable object</ins> and may unlock
the <del>mutex</del><ins>lockable object</ins> during the lock's
destruction (such as when leaving block scope). A thread of execution
may use a lock to aid in managing <del>mutex</del> ownership <ins>of a
lockable object</ins> in an exception safe manner. A lock is said to
own a <del>mutex</del><ins>lockable object</ins> if it is currently
managing the ownership of that <del>mutex</del><ins>lockable
object</ins> for a thread of execution. A lock does not manage the
lifetime of the <del>mutex</del><ins>lockable object</ins> it
references.  [ Note: Locks are intended to ease the burden of
unlocking the <del>mutex</del><ins>lockable object</ins> under both
normal and exceptional circumstances. &mdash; end note ]
</p></blockquote>

<p>32.6.5 <a href="https://wg21.link/thread.lock">[thread.lock]</a> paragaph 2:</p>

<blockquote><p>
2 Some lock constructors take tag types which describe what should be
done with the <del>mutex</del><ins>lockable</ins> object during the
lock's constuction.
</p></blockquote>

<p>32.6.5.2 <a href="https://wg21.link/thread.lock.guard">[thread.lock.guard]</a> paragaph 1:</p>

<blockquote><p>
1 An object of type <code>lock_guard</code> controls the ownership of a
  <del>mutex</del><ins>lockable</ins> object within a scope. A
<code>lock_guard</code> object maintains ownership of
a <del>mutex</del><ins>lockable</ins> object throughout
the <code>lock_guard</code> object's lifetime. The behavior of a program
is undefined if the <del>mutex</del><ins>lockable object</ins>
referenced by <code>pm</code> does not exist for the entire lifetime (3.8)
of the <code>lock_guard</code> object. <ins><code>Mutex</code> shall meet
  the <code>Lockable</code> requirements (30.2.5.1).</ins>
</p></blockquote>

<p>32.6.5.4 <a href="https://wg21.link/thread.lock.unique">[thread.lock.unique]</a> paragaph 1:</p>

<blockquote><p>
1 An object of type <code>unique_lock</code> controls the ownership of
a <del>mutex</del><ins>lockable object</ins> within a
scope. <del>Mutex</del> <del>o</del><ins>O</ins>wnership <ins>of the
lockable object</ins> may be acquired at construction or after
construction, and may be transferred, after acquisition, to
another <code>unique_lock</code> object. Objects of
type <code>unique_lock</code> are not copyable but are movable. The
behavior of a program is undefined if the contained
pointer <code>pm</code> is not null and the mutex pointed to
by <code>pm</code> does not exist for the entire remaining lifetime (3.8)
of the <code>unique_lock</code> object. <ins><code>Mutex</code> shall meet
the <code>Lockable</code> requirements (30.2.5.1).</ins>
</p></blockquote>


<p>
Add the following to the precondition of <code>unique_lock(mutex_type&amp;
m, const chrono::time_point&lt;Clock, Duration&gt;&amp; abs_time)</code> in 
32.6.5.4.2 <a href="https://wg21.link/thread.lock.unique.cons">[thread.lock.unique.cons]</a> paragraph 18:
</p>

<blockquote><pre>template &lt;class Clock, class Duration&gt;
  unique_lock(mutex_type&amp; m, const chrono::time_point&lt;Clock, Duration&gt;&amp; abs_time);
</pre>

<blockquote><p>
18 <i>Requires:</i> If <code>mutex_type</code> is not a recursive mutex 
the calling thread does not own the mutex. <ins>The supplied <code>mutex_type</code>
type shall meet the <code>TimedLockable</code> requirements (30.2.5.2).</ins>
</p></blockquote>
</blockquote>

<p>
Add the following to the precondition of <code>unique_lock(mutex_type&amp;
 m,
const chrono::duration&lt;Rep, Period&gt;&amp; rel_time)</code> in 
32.6.5.4.2 <a href="https://wg21.link/thread.lock.unique.cons">[thread.lock.unique.cons]</a>
paragraph 22
</p>

<blockquote><p>
22  <i>Requires:</i> If <code>mutex_type</code> is not a recursive mutex
 the
calling thread does not own the mutex. <ins>The supplied <code>mutex_type</code>
type shall meet the <code>TimedLockable</code> requirements (30.2.5.2).</ins>
</p></blockquote>

<p>
Add the following as a precondition of <code>bool try_lock_until(const
chrono::time_point&lt;Clock, Duration&gt;&amp; abs_time)</code> before
32.6.5.4.3 <a href="https://wg21.link/thread.lock.unique.locking">[thread.lock.unique.locking]</a> paragraph 8
</p>

<blockquote><pre>template &lt;class Clock, class Duration&gt;
  bool try_lock_until(const chrono::time_point&lt;Clock, Duration&gt;&amp; abs_time);
</pre>
<blockquote><p><ins>
<i>Requires:</i> The supplied <code>mutex_type</code> type shall meet the
<code>TimedLockable</code> requirements (30.2.5.2).
</ins></p></blockquote>
</blockquote>

<p>
Add the following as a precondition of <code>bool try_lock_for(const
chrono::duration&lt;Rep, Period&gt;&amp; rel_time)</code> before 
32.6.5.4.3 <a href="https://wg21.link/thread.lock.unique.locking">[thread.lock.unique.locking]</a> paragraph 12
</p>

<blockquote><pre>template &lt;class Rep, class Period&gt;
  bool try_lock_for(const chrono::duration&lt;Rep, Period&gt;&amp; rel_time);
</pre>
<blockquote><p><ins>
<i>Requires:</i> The supplied <code>mutex_type</code> type shall meet the
<code>TimedLockable</code> requirements (30.2.5.2).
</ins></p></blockquote>
</blockquote>

<p>
Replace 32.6.6 <a href="https://wg21.link/thread.lock.algorithm">[thread.lock.algorithm]</a> p1 with the following:
</p>

<blockquote><pre>template &lt;class L1, class L2, class... L3&gt; int try_lock(L1&amp;, L2&amp;, L3&amp;...);
</pre>
<blockquote><p>
1 <i>Requires:</i> Each template parameter type shall meet the
<code><del>Mutex</del> <ins>Lockable</ins></code> requirements
<ins>(30.2.5.1).</ins><del>, except that a call to <code>try_lock()</code> 
may throw an exception.</del> [<i>Note:</i> The <code>unique_lock</code> class 
template meets these requirements when suitably instantiated. &mdash; <i>end note</i>]
</p></blockquote>
</blockquote>

<p>
Replace 32.6.6 <a href="https://wg21.link/thread.lock.algorithm">[thread.lock.algorithm]</a> p4 with the following:
</p>

<blockquote><pre>template &lt;class L1, class L2, class... L3&gt; void lock(L1&amp;, L2&amp;, L3&amp;...);
</pre>
<blockquote><p>
4 <i>Requires:</i> Each template parameter type shall meet the
<code>Mutex<del>Mutex</del> <ins>Lockable</ins></code>
requirements <ins>(30.2.5.1).</ins><del>, except that a call to
<code>try_lock()</code> may throw an exception.</del> [<i>Note:</i> The
<code>unique_lock</code> class template meets these requirements when 
suitably instantiated. &mdash; <i>end note</i>]
</p></blockquote>
</blockquote>

<p>
Replace 32.7.5 <a href="https://wg21.link/thread.condition.condvarany">[thread.condition.condvarany]</a> paragraph 1 with:
</p>

<blockquote><p>
1 A <code>Lock</code> type shall meet the <del>requirements for a <code>Mutex</code>
type</del> <ins><code>Lockable</code> requirements (30.2.5.1)</ins>, except 
that <code>try_lock</code> is not required. [<i>Note:</i> All of the standard 
mutex types meet this requirement. &mdash; <i>end note</i>]
</p></blockquote>






</body>
</html>
