|
Boost-Commit : |
From: bdawes_at_[hidden]
Date: 2007-12-01 09:06:31
Author: bemandawes
Date: 2007-12-01 09:06:30 EST (Sat, 01 Dec 2007)
New Revision: 41531
URL: http://svn.boost.org/trac/boost/changeset/41531
Log:
Resolve all of Pete's issues relating to 30.2.3, Locks, and its subsections.
Text files modified:
sandbox/committee/LWG/Pete_comments.html | 42 ++++++-
sandbox/committee/LWG/thread_library.html | 215 ++++++++++++++++-----------------------
2 files changed, 123 insertions(+), 134 deletions(-)
Modified: sandbox/committee/LWG/Pete_comments.html
==============================================================================
--- sandbox/committee/LWG/Pete_comments.html (original)
+++ sandbox/committee/LWG/Pete_comments.html 2007-12-01 09:06:30 EST (Sat, 01 Dec 2007)
@@ -87,30 +87,56 @@
</li>
<li>Timed Mutexes, Effects needs tightening.<br>
</li>
- <li>Class lock_guard: what does "Mutex ownership cannot be deferred" mean?<br>
+ <li>✔ Class lock_guard: what does "Mutex ownership cannot be deferred" mean?<br>
+ <br>
+ <i>The full paragraph now reads: "An object of type
+<code>lock_guard</code> controls the ownership of a mutex within a single scope.
+ A <code>lock_guard</code> object
+ maintains ownership of a
+mutex throughout the <code>lock_guard</code>'s lifetime.
+Mutex ownership can not be deferred
+or transferred away from the <code>lock_guard</code>." The last sentence appears
+ to add no additional information and so has been removed.</i><br>
</li>
- <li>lock_guard, precondition: what does it mean for the lifetime of an object
+ <li>✔ lock_guard, precondition: what does it mean for the lifetime of an object
to be greater than the lifetime of another object? Further, it can't be a
precondition that the mutex still be in existence after the call, since that's
not "pre" (i.e. there's no way to test this condition on entry into the
function).<br>
+ <br>
+ <i>Reworded, added reference to </i><span style="font-style: italic">([basic.life])
+ to make clear what definition of "lifetime" applies, changed
+ lifetime requirement violation undefined behavior.</span><br>
</li>
- <li>unique_lock constructors: constructors that take mutex say that the object
+ <li>✔ unique_lock constructors: constructors that take mutex say that the object
stores a reference to the passed mutex; what does that reference refer to
after default construction?<br>
+ <br>
+ <i>Fixed. The fix involved adding private members and much editing. Also
+ realized that issue 16 applied to unique_lock too, so applied its resolution.</i><br>
</li>
- <li>unique_lock move constructor "transfers mutex ownership". What does this
+ <li>✔ unique_lock move constructor "transfers mutex ownership". What does this
mean?<br>
- </li>
- <li>unique_lock::timed_lock: describes handling when the resolution of
+ <br>
+ <i>Fixed. Extraneous wording removed. Postconditions are sufficient to specify
+ transfer of ownership.<br>
+ </i></li>
+ <li>✔ unique_lock::timed_lock: describes handling when the resolution of
TimeDuration is greater than the native resolution; seems like this belongs in
the description of mutex lock, not in this forwarder.<br>
+ <br>
+ <i>Fixed.</i><br>
</li>
- <li>unique_lock::unspecified-bool-type: returns null or non-null. Seems to be
+ <li>✔ unique_lock::unspecified-bool-type: returns null or non-null. Seems to be
assuming (or imposing) constraints on the type returned.<br>
+ <br>
+ <i>Fixed. The idiom has been changed to use the new explicit operator bool.</i><br>
</li>
- <li>unique_lock assignment operator: what is the "lock count" of a recursive
+ <li>✔ unique_lock assignment operator: what is the "lock count" of a recursive
mutex?<br>
+ <br>
+ <i>Fixed. Wording changed. Wording posted to list to make sure others are
+ happy with it.</i><br>
</li>
<li>generic locking algorithms: is there a requirement that the locks be
attempted in any particular order?<br>
Modified: sandbox/committee/LWG/thread_library.html
==============================================================================
--- sandbox/committee/LWG/thread_library.html (original)
+++ sandbox/committee/LWG/thread_library.html 2007-12-01 09:06:30 EST (Sat, 01 Dec 2007)
@@ -1684,21 +1684,21 @@
lock_guard(lock_guard const&) = delete;
lock_guard& operator=(lock_guard const&) = delete;
+
+private:
+ mutex_type* pm; // for exposition only
};
-} // std
-</code></pre>
+} // std</code></pre>
</blockquote>
<p>
-<code>lock_guard</code>
-is used to control the ownership of a mutex within a single scope.
-An invariant of the <code>lock_guard</code> object
-is that it maintains the ownership of the
-mutex throughout the <code>lock_guard</code>'s lifetime.
-Mutex ownership can not be deferred
-or transferred away from the <code>lock_guard</code>.
-</p>
+An object of type
+<code>lock_guard</code> controls the ownership of a mutex within a scope. A <code>lock_guard</code> object
+maintains ownership of a
+mutex throughout the <code>lock_guard</code>'s lifetime. Behavior is undefined
+if the mutex pointed to by <code><var>pm</var></code> does not<span style="font-style: normal"> exist for the
+entire lifetime ([basic.life]) of the </span> <code>lock_guard</code><span style="font-style: normal"> object.</span></p>
<pre><code>
explicit lock_guard(mutex_type& <var>m</var>);
@@ -1708,16 +1708,12 @@
<dl>
<dt>Precondition:</dt>
<dd>
-If <code>mutex_type</code> is not a recursive mutex, the current thread
-does not own the mutex.
-The lifetime of <code><var>m</var></code> includes the lifetime
-of the <code>lock_guard</code> object.
-</dd>
+If <code>mutex_type</code> is not a recursive mutex, the current thread does not
+own mutex <code>m</code>.</dd>
<dt>Effects:</dt>
<dd>
-Stores a reference to <code><var>m</var></code>
-and calls <code><var>m</var>.lock()</code>.
+<code><var>pm = &m</var>;<var> m</var>.lock()</code>.
</dd>
</dl>
</blockquote>
@@ -1730,15 +1726,12 @@
<dl>
<dt>Precondition:</dt>
<dd>
-The current thread has ownership of the mutex <code><var>m</var></code>.
-The lifetime of <code><var>m</var></code> includes the lifetime of the
-<code>lock_guard</code> object.
+The current thread owns mutex <code><var>m</var></code>.
</dd>
<dt>Effects:</dt>
<dd>
-Stores a reference to <code><var>m</var></code>
-and performs no other operation on it.
+<code><var>pm = &m</var></code>.
</dd>
</dl>
</blockquote>
@@ -1804,6 +1797,10 @@
void swap(unique_lock&& <var>u</var>);
mutex_type* release();
+
+private:
+ mutex_type* pm; // for exposition only
+ bool owns; // for exposition only
};
template <class Mutex> void swap(unique_lock<Mutex>& <var>x</var>, unique_lock<Mutex>& <var>y</var>);
@@ -1815,13 +1812,16 @@
</blockquote>
<p>
-<code>unique_lock</code>
-is used to control the ownership of a mutex within one or more scopes.
+An object of type
+<code>unique_lock</code> controls the ownership of a mutex within a scope.
Mutex ownership
-can be deferred or transferred away from the <code>unique_lock</code>.
+may be acquired at construction or subsequent to construction, and subsequent to
+acquisition may be transferred to another <code>unique_lock</code> object.
An object of type
-<code>unique_lock</code> is not copyable but is movable.
-</p>
+<code>unique_lock</code> is not copyable but is movable. Behavior is undefined
+if <code>mutex() != 0</code> and the mutex pointed to by <code>mutex()</code>
+does not<span style="font-style: normal"> exist for the entire remaining lifetime ([basic.life]) of the
+<code>unique_lock</code> object.</span></p>
<pre><code>
unique_lock();
@@ -1831,8 +1831,7 @@
<dl>
<dt>Effects:</dt>
<dd>
-Constructs an object of type <code>unique_lock</code>.
-</dd>
+Constructs an object of type <code>unique_lock</code>.</dd>
<dt>Postconditions:</dt>
<dd>
@@ -1851,16 +1850,12 @@
<dl>
<dt>Precondition:</dt>
<dd>
-If <code>mutex_type</code> is not a recursive mutex, the current thread
-does not own the mutex.
-The lifetime of <code><var>m</var></code> includes the lifetime
-of the <code>unique_lock</code> object.
-</dd>
+If <code>mutex_type</code> is not a recursive mutex, the current thread does not
+own the mutex.</dd>
<dt>Effects:</dt>
<dd>
-Stores a reference to <code><var>m</var></code>
-and calls <code><var>m</var>.lock()</code>.
+Constructs an object of type <code>unique_lock</code>, calls<code><var> m</var>.lock()</code>.
</dd>
<dt>Postconditions:</dt>
@@ -1880,17 +1875,12 @@
<dl>
<dt>Precondition:</dt>
<dd>
-If <code>mutex_type</code> is not a recursive mutex, the current thread
-does not own the mutex.
-The lifetime of <code><var>m</var></code> includes the lifetime of the <code>
-unique_lock</code> object.
-</dd>
+If <code>mutex_type</code> is not a recursive mutex, the current thread does not
+own the mutex.</dd>
<dt>Effects:</dt>
<dd>
-Stores a reference to <code><var>m</var></code>
-and performs no other operation on it.
-</dd>
+Constructs an object of type <code>unique_lock</code>.</dd>
<dt>Postconditions:</dt>
<dd>
@@ -1909,16 +1899,12 @@
<dl>
<dt>Precondition:</dt>
<dd>
-If <code>mutex_type</code> is not a recursive mutex, then the current thread
-does not own the mutex.
-The lifetime of <code><var>m</var></code> includes the lifetime of the <code>
-unique_lock</code> object.
-</dd>
+If <code>mutex_type</code> is not a recursive mutex, then the current thread
+does not own the mutex.</dd>
<dt>Effects:</dt>
<dd>
-Stores a reference to <code><var>m</var></code>
-and calls <code><var>m</var>.try_lock()</code>.
+Constructs an object of type <code>unique_lock</code>, calls<code><var> m</var>.try_lock()</code>.
</dd>
<dt>Postconditions:</dt>
@@ -1939,23 +1925,18 @@
<dl>
<dt>Precondition:</dt>
<dd>
-The current thread has ownership of the mutex <code><var>m</var></code>.
-The lifetime of <code><var>m</var></code> includes the lifetime of the <code>
-unique_lock</code> object.
-</dd>
+The current thread owns mutex <code><var>m</var></code>.</dd>
<dt>Effects:</dt>
<dd>
-Stores a reference to <code><var>m</var></code>
-and performs no other operation on it.
+Constructs an object of type <code>unique_lock</code>.
</dd>
<dt>Postconditions:</dt>
<dd>
<code>mutex() == &<var>m</var></code>
<br>
-<code>owns_lock() == true</code>
-</dd>
+<code>owns_lock() == true</code></dd>
</dl>
</blockquote>
@@ -1967,16 +1948,13 @@
<dl>
<dt>Precondition:</dt>
<dd>
-If <code>mutex_type</code> is not a recursive mutex, then the current thread
-does not own the mutex.
-The lifetime of <code><var>m</var></code> includes the lifetime of the <code>
-unique_lock</code> object.
-</dd>
+If <code>mutex_type</code> is not a recursive mutex, then the current thread
+does not own the mutex.</dd>
<dt>Effects:</dt>
<dd>
-Stores a reference to <code><var>m</var></code>
-and calls <code><var>m</var>.timed_lock(abs_time)</code>.
+Constructs an object of type <code>unique_lock</code>
+and calls <code><var>m</var>.timed_lock(<var>abs_time</var>)</code>.
</dd>
<dt>Postconditions:</dt>
@@ -2008,16 +1986,12 @@
<dl>
<dt>Precondition:</dt>
<dd>
-If <code>mutex_type</code> is not a recursive mutex, then the current thread
-does not own the mutex.
-The lifetime of <code><var>m</var></code> includes the lifetime of the <code>
-unique_lock</code> object.
-</dd>
+If <code>mutex_type</code> is not a recursive mutex, then the current thread
+does not own the mutex.</dd>
<dt>Effects:</dt>
<dd>
-Stores a reference to <code><var>m</var></code>
-and calls <code><var>m</var>.timed_lock(rel_time)</code>.
+Constructs an object of type <code>unique_lock </code>and calls <code><var>m</var>.timed_lock(<var>rel_time</var>)</code>.
</dd>
<dt>Postconditions:</dt>
@@ -2039,9 +2013,7 @@
<dt>Effects:</dt>
<dd>
If <code>owns_lock()</code>
-calls <code>unlock()</code> on the referenced mutex.
-Otherwise there are no effects.
-</dd>
+calls <code>mutex()->unlock()</code>.</dd>
<dt>Throws:</dt>
<dd>
@@ -2056,24 +2028,21 @@
<blockquote>
<dl>
-<dt>Effects:</dt>
-<dd>
-Transfers mutex ownership (if any)
-from <code><var>u</var></code> to <code>this</code>.
-</dd>
<dt>Postconditions:</dt>
<dd>
-<code><var>u</var>.mutex() == 0</code>
-<br>
-<code><var>u</var>.owns_lock() == false</code>
-<br>
<code>mutex() ==</code>
-the value of <code><var>u</var>.mutex()</code> prior to the construction.
+the value of <code><var>u</var>.mutex()</code> prior to establishment of
+postconditions on <i><code>u</code></i>.
<br>
<code>owns_lock() ==</code>
-the value of <code><var>u</var>.owns_lock()</code> prior to the construction.
-</dd>
+the value of <code><var>u</var>.owns_lock()</code> prior to establishment of
+postconditions on <i><code>u</code></i>.<code><var><br>
+u</var>.mutex() == 0</code>
+<br>
+<code><var>u</var>.owns_lock() == false</code>
+<br>
+ </dd>
<dt>Throws:</dt>
<dd>
@@ -2090,31 +2059,21 @@
<dl>
<dt>Effects:</dt>
<dd>
-If <code>owns_lock()</code> calls <code>unlock()</code>, and then
-transfers mutex ownership (if any)
-from <code><var>u</var></code> to <code>this</code>.
-[<i>Note:</i>
-With a recursive mutex it is possible that both
-<code>this</code> and <code><var>u</var></code>
-own the same mutex before the assignment.
-In this case, <code>this</code> will own the mutex after the assignment (and
-<code><var>u</var></code> will not),
-but the mutex's lock count will be decremented by
-one.
-—<i>end note</i>]
+If <code>owns_lock()</code> calls <code>mutex()->unlock()</code>.
</dd>
<dt>Postconditions:</dt>
<dd>
-<code><var>u</var>.mutex() == 0</code>
-<br>
-<code><var>u</var>.owns_lock() == false</code>
-<br>
<code>mutex() ==</code>
-the value of <code><var>u</var>.mutex()</code> prior to the construction.
+the value of <code><var>u</var>.mutex()</code> prior to establishment of
+postconditions on <i><code>u</code></i>.
<br>
<code>owns_lock() ==</code>
-the value of <code><var>u</var>.owns_lock()</code> prior to the construction.
+the value of <code><var>u</var>.owns_lock()</code> prior to establishment of
+postconditions on <i><code>u</code></i>.<code><var><br>
+u</var>.mutex() == 0</code>
+<br>
+<code><var>u</var>.owns_lock() == false</code>
</dd>
<dt>Throws:</dt>
@@ -2122,6 +2081,14 @@
Nothing.
</dd>
</dl>
+<p>[<i>Note:</i>
+With a recursive mutex it is possible that both
+<code>*this</code> and <code><var>u</var></code>
+own the same mutex before the assignment.
+In this case, <code>*this</code> will own the mutex after the assignment (and
+<code><var>u</var></code> will not), and the mutex will have one less level of
+recursion.
+—<i>end note</i>] </p>
</blockquote>
<pre><code>
@@ -2132,7 +2099,7 @@
<dl>
<dt>Effects:</dt>
<dd>
-Calls <code>lock()</code> on the referenced mutex.
+<code>mutex()->lock()</code>.
</dd>
<dt>Postconditions:</dt>
@@ -2142,8 +2109,7 @@
<dt>Throws:</dt>
<dd>
-<code>lock_error</code>,
-if on entry <code>owns_lock()</code> is <code>true</code> or if <code>mutex() == 0</code>.
+<code>lock_error</code>, if on entry <code>owns_lock()</code> is <code>true</code> or if <code>mutex() == 0</code>.
</dd>
</dl>
</blockquote>
@@ -2156,19 +2122,19 @@
<dl>
<dt>Effects:</dt>
<dd>
-Calls <code>try_lock()</code> on the referenced mutex.
+<code>mutex()->try_lock()</code>.
</dd>
<dt>Returns:</dt>
<dd>
-The result of the call to <code>try_lock()</code> on the referenced mutex.
+The result of the call to <code>try_lock()</code>.
</dd>
<dt>Postconditions:</dt>
<dd>
<code>owns_lock() ==</code>
the result
-of the call to <code>try_lock()</code> on the referenced mutex.
+of the call to <code>try_lock()</code>.
</dd>
<dt>Throws:</dt>
@@ -2188,20 +2154,19 @@
<dl>
<dt>Effects:</dt>
<dd>
-Calls <code>timed_lock(rel_t)</code> on the referenced mutex.
+<code>mutex()->timed_lock(rel_t)</code>.
</dd>
<dt>Returns:</dt>
<dd>
-The result of the call to <code>timed_lock(rel_t)</code>
-on the referenced mutex.
+The result of the call to <code>timed_lock(rel_t)</code>.
</dd>
<dt>Postconditions:</dt>
<dd>
<code>owns_lock() == </code>
the result
-of the call to <code>timed_lock(rel_t)</code> on the referenced mutex.
+of the call to <code>timed_lock(rel_t)</code>.
</dd>
<dt>Throws:</dt>
@@ -2220,20 +2185,19 @@
<dl>
<dt>Effects:</dt>
<dd>
-Calls <code>timed_lock(abs_t)</code> on the referenced mutex.
+<code>mutex()->timed_lock(abs_t)</code>.
</dd>
<dt>Returns:</dt>
<dd>
-The result of the call to <code>timed_lock(rel_t)</code>
-on the referenced mutex.
+The result of the call to <code>timed_lock(rel_t)</code>.
</dd>
<dt>Postconditions:</dt>
<dd>
<code>owns_lock() == </code>
the result
-of the call to <code>timed_lock(rel_t)</code> on the referenced mutex.
+of the call to <code>timed_lock(rel_t)</code>.
</dd>
<dt>Throws:</dt>
@@ -2252,7 +2216,7 @@
<dl>
<dt>Effects:</dt>
<dd>
-Calls <code>unlock()</code> on the referenced mutex.
+<code>mutex()->unlock()</code>.
</dd>
<dt>Postconditions:</dt>
@@ -2276,8 +2240,7 @@
<dl>
<dt>Returns:</dt>
<dd>
-<code>true</code> if <code>this</code> owns a lock on a referenced mutex,
-else <code>false</code>.
+<code><var>owns</var></code>.
</dd>
<dt>Throws:</dt>
@@ -2313,7 +2276,7 @@
<dl>
<dt>Returns:</dt>
<dd>
-A pointer to the referenced mutex, or null if there is no referenced mutex.
+<code><var>pm</var></code>.
</dd>
<dt>Throws:</dt>
@@ -2331,7 +2294,7 @@
<dl>
<dt>Effects:</dt>
<dd>
-Swaps state with <code><var>u</var></code>.
+Swaps each data member of <code>*this</code> with the equivalent data member of <code><var>u</var></code>.
</dd>
<dt>Throws:</dt>
@@ -2349,7 +2312,7 @@
<dl>
<dt>Returns:</dt>
<dd>
-A pointer to the referenced mutex, or null if there is no referenced mutex.
+<code><var>pm</var></code>.
</dd>
<dt>Postconditions:</dt>
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk