$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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>