<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
  "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd" [
  <!ENTITY % thread.entities SYSTEM "entities.xml">
  %thread.entities;
]>
<!-- Copyright (c) 2002-2003 William E. Kempf, Michael Glassford
     Subject to the Boost Software License, Version 1.0. 
     (See accompanying file LICENSE-1.0 or  http://www.boost.org/LICENSE-1.0)
-->
<section id="thread.concepts" last-revision="$Date: 2007/01/02 21:44:39 $">
	<title>Concepts</title>

	<para>&Boost.Thread; currently supports two types of mutex concepts:
	ordinary <link linkend="thread.concepts.mutexes">Mutexes</link>,
	which allow only one thread at a time to access a resource, and
	<link linkend="thread.concepts.read-write-mutexes">Read/Write Mutexes</link>,
	which allow only one thread at a time to access a resource when it is
	being modified (the "Write" part of Read/Write), but allows multiple threads
	to access a resource when it is only being referenced (the "Read" part of
    Read/Write).</para> 
    <note> Unfortunately it turned out that the current implementation of Read/Write Mutex has     
            some serious problems. So it was decided not to put this implementation into
            release grade code. Also discussions on the mailing list led to the
            conclusion that the current concepts need to be rethought. In particular
            the schedulings <link linkend="thread.concepts.read-write-scheduling-policies.inter-class">
                Inter-Class Scheduling Policies</link> are deemed unnecessary.
            There seems to be common belief that a fair scheme suffices.
            The following documentation has been retained however, to give
            readers of this document the opportunity to study the original design.
    </note>

	<section id="thread.concepts.mutexes">
		<title>Mutexes</title>

		<note>Certain changes to the mutexes and lock concepts are
		currently under discussion. In particular, the combination of
		the multiple lock concepts into a single lock concept
		is likely, and the combination of the multiple mutex
		concepts into a single mutex concept is also possible.</note>
		
		<para>A mutex (short for mutual-exclusion) object is used to serialize
		access to a resource shared between multiple threads. The
		<link linkend="thread.concepts.Mutex">Mutex</link> concept, with
		<link linkend="thread.concepts.TryMutex">TryMutex</link> and
		<link linkend="thread.concepts.TimedMutex">TimedMutex</link> refinements,
		formalize the requirements. A model that implements Mutex and its
		refinements has two states: <emphasis role="bold">locked</emphasis> and
		<emphasis role="bold">unlocked</emphasis>. Before using a shared resource, a
		thread locks a &Boost.Thread; mutex object
		(an object whose type is a model of
		<link linkend="thread.concepts.Mutex">Mutex</link> or one of it's
		refinements), ensuring
		<link linkend="thread.glossary.thread-safe">thread-safe</link> access to
		the shared resource. When use of the shared resource is complete, the thread
		unlocks the mutex object, allowing another thread to acquire the lock and
		use the shared resource.</para>
		<para>Traditional C thread APIs, like POSIX threads or the Windows thread
		APIs, expose functions to lock and unlock a mutex object. This is dangerous
		since it's easy to forget to unlock a locked mutex. When the flow of control
		is complex, with multiple return points, the likelihood of forgetting to
		unlock a mutex object becomes even greater. When exceptions are thrown,
		it becomes nearly impossible to ensure that the mutex object is unlocked
		properly when using these traditional API's. The result is
		<link linkend="thread.glossary.deadlock">deadlock</link>.</para>
		<para>Many C++ threading libraries use a pattern known as <emphasis>Scoped
		Locking</emphasis> &cite.SchmidtStalRohnertBuschmann; to free the programmer from
		the need to explicitly lock and unlock mutex objects. With this pattern, a
		<link linkend="thread.concepts.lock-concepts">Lock</link> concept is employed where
		the lock object's constructor locks the associated mutex object and the
		destructor automatically does the unlocking. The
		&Boost.Thread; library takes this pattern to
		the extreme in that Lock concepts are the only way to lock and unlock a
		mutex object: lock and unlock functions are not exposed by any
		&Boost.Thread; mutex objects. This helps to
		ensure safe usage patterns, especially when code throws exceptions.</para>

		<section id="thread.concepts.locking-strategies">
			<title>Locking Strategies</title>
			
			<para>Every mutex object follows one of several locking strategies. These
			strategies define the semantics for the locking operation when the calling
			thread already owns a lock on the mutex object.</para>
			
			<section id="thread.concepts.recursive-locking-strategy">
				<title>Recursive Locking Strategy</title>
			
				<para>With a recursive locking strategy, when a thread attempts to acquire
				a lock on the mutex object for which it already owns a lock, the operation
				is successful. Note the distinction between a thread, which may have
				multiple locks outstanding on a recursive mutex object, and a lock object,
				which even for a recursive mutex object cannot have any of its lock
				functions called multiple times without first calling unlock.</para>
				
				<para>Internally a lock count is maintained and the owning thread must
				unlock the mutex object the same number of times that it locked it before
				the mutex object's state returns to unlocked. Since mutex objects in
				&Boost.Thread; expose locking
				functionality only through lock concepts, a thread will always unlock a
				mutex object the same number of times that it locked it. This helps to
				eliminate a whole set of errors typically found in traditional C style
				thread APIs.</para>
				
				<para>Classes <classname>boost::recursive_mutex</classname>,
				<classname>boost::recursive_try_mutex</classname> and
				<classname>boost::recursive_timed_mutex</classname> use this locking
				strategy.</para>
			</section>
			
			<section id="thread.concepts.checked-locking-strategy">
				<title>Checked Locking Strategy</title>
				
				<para>With a checked locking strategy, when a thread attempts to acquire a
				lock on the mutex object for which the thread already owns a lock, the
				operation will fail with some sort of error indication. Further, attempts
				by a thread to unlock a mutex object that was not locked by the thread
				will also return some sort of error indication. In
				&Boost.Thread;, an exception of type
				<classname>boost::lock_error</classname> 
				would be thrown in these cases.</para>
				
				<para>&Boost.Thread; does not currently
				provide any mutex objects that use this strategy.</para>
			</section>
			
			<section id="thread.concepts.unchecked-locking-strategy">
				<title>Unchecked Locking Strategy</title>
				
				<para>With an unchecked locking strategy, when a thread attempts to acquire
				a lock on a mutex object for which the thread already owns a lock the
				operation will
				<link linkend="thread.glossary.deadlock">deadlock</link>. In general
				this locking strategy is less safe than a checked or recursive strategy,
				but it's also a faster strategy and so is employed by many libraries.</para>
				
				<para>&Boost.Thread; does not currently
				provide any mutex objects that use this strategy.</para>
			</section>
			
			<section id="thread.concepts.unspecified-locking-strategy">
				<title>Unspecified Locking Strategy</title>
				
				<para>With an unspecified locking strategy, when a thread attempts to
				acquire a lock on a mutex object for which the thread already owns a lock
				the operation results in 
				<link linkend="thread.glossary.undefined-behavior">undefined behavior</link>.
				</para>
				
				<para>In general a mutex object with an unspecified locking strategy is
				unsafe, and it requires programmer discipline to use the mutex object
				properly. However, this strategy allows an implementation to be as fast as
				possible with no restrictions on its implementation. This is especially
				true for portable implementations that wrap the native threading support
				of a platform. For this reason, the classes
				<classname>boost::mutex</classname>,
				<classname>boost::try_mutex</classname> and
				<classname>boost::timed_mutex</classname> use this locking strategy
				despite the lack of safety.</para>
			</section>
		</section>
		
		<section id="thread.concepts.sheduling-policies">
			<title>Scheduling Policies</title>
			
			<para>Every mutex object follows one of several scheduling policies. These
			policies define the semantics when the mutex object is unlocked and there is
			more than one thread waiting to acquire a lock. In other words, the policy
			defines which waiting thread shall acquire the lock.</para>
			
			<section id="thread.concepts.FIFO-scheduling-policy">
				<title>FIFO Scheduling Policy</title>
				
				<para>With a FIFO ("First In First Out") scheduling policy, threads waiting 
				for the lock will acquire it in a first-come-first-served order.
				This can help prevent a high priority thread from starving lower priority
				threads that are also waiting on the mutex object's lock.</para>
			</section>
			
			<section id="thread.concepts.priority-driven-scheduling-policy">
				<title>Priority Driven Policy</title>
				
				<para>With a Priority Driven scheduling policy, the thread with the
				highest priority acquires the lock. Note that this means that low-priority
				threads may never acquire the lock if the mutex object has high contention
				and there is always at least one high-priority thread waiting. This is
				known as thread starvation. When multiple threads of the same priority are
				waiting on the mutex object's lock one of the other scheduling priorities
				will determine which thread shall acquire the lock.</para>
			</section>
			
			<section id="thread.concepts.unspecified-scheduling-policy">
				<title>Unspecified Policy</title>
				
				<para>The mutex object does not specify a scheduling policy. In order to
				ensure portability, all &Boost.Thread;
				mutex objects use an unspecified scheduling policy.</para>
			</section>
		</section>
		
		<section id="thread.concepts.mutex-concepts">
			<title>Mutex Concepts</title>
			
			<section id="thread.concepts.Mutex">
				<title>Mutex Concept</title>
				
				<para>A Mutex object has two states: locked and unlocked. Mutex object
				state can only be determined by a lock object meeting the
				appropriate lock concept requirements
				and constructed for the Mutex object.</para>
				
				<para>A Mutex is
				<ulink url="../../libs/utility/utility.htm#Class%20noncopyable">
				NonCopyable</ulink>.</para>
				<para>For a Mutex type <code>M</code>
				and an object <code>m</code> of that type, 
				the following expressions must be well-formed
				and have the indicated effects.</para>
				
				<table>
					<title>Mutex Expressions</title>
					
					<tgroup cols="2">
						<thead>
							<row>
								<entry>Expression</entry>
								<entry>Effects</entry>
							</row>
						</thead>
						
						<tbody>
							<row>
								<entry>M m;</entry>
								<entry><para>Constructs a mutex object m.</para>
								<para>Postcondition: m is unlocked.</para></entry>
							</row>
							<row>
								<entry>(&amp;m)-&gt;~M();</entry>
								<entry>Precondition: m is unlocked. Destroys a mutex object
								m.</entry>
							</row>
							<row>
								<entry>M::scoped_lock</entry>
								<entry>A model of
								<link linkend="thread.concepts.ScopedLock">ScopedLock</link>
								</entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
		
			<section id="thread.concepts.TryMutex">
				<title>TryMutex Concept</title>
				
				<para>A TryMutex is a refinement of
				<link linkend="thread.concepts.Mutex">Mutex</link>. 
				For a TryMutex type <code>M</code>
				and an object <code>m</code> of that type, 
				the following expressions must be well-formed 
				and have the indicated effects.</para>
				
				<table>
					<title>TryMutex Expressions</title>
					
					<tgroup cols="2">
						<thead>
							<row>
								<entry>Expression</entry>
								<entry>Effects</entry>
							</row>
						</thead>
						
						<tbody>
							<row>
								<entry>M::scoped_try_lock</entry>
								<entry>A model of
								<link linkend="thread.concepts.ScopedTryLock">ScopedTryLock</link>
								</entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
		
			<section id="thread.concepts.TimedMutex">
				<title>TimedMutex Concept</title>
				
				<para>A TimedMutex is a refinement of
				<link linkend="thread.concepts.TryMutex">TryMutex</link>. 
				For a TimedMutex type <code>M</code>
				and an object <code>m</code> of that type, 
				the following expressions must be well-formed
				and have the indicated effects.</para>
				
				<table>
					<title>TimedMutex Expressions</title>
					
					<tgroup cols="2">
						<thead>
							<row>
								<entry>Expression</entry>
								<entry>Effects</entry>
							</row>
						</thead>
						
						<tbody>
							<row>
								<entry>M::scoped_timed_lock</entry>
								<entry>A model of
								<link
								linkend="thread.concepts.ScopedTimedLock">ScopedTimedLock</link>
								</entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
		</section>
		
		<section id="thread.concepts.mutex-models">
			<title>Mutex Models</title>
			
			<para>&Boost.Thread; currently supplies six models of
			<link linkend="thread.concepts.Mutex">Mutex</link>
			and its refinements.</para>
			
			<table>
				<title>Mutex Models</title>
				
				<tgroup cols="3">
					<thead>
						<row>
							<entry>Concept</entry>
							<entry>Refines</entry>
							<entry>Models</entry>
						</row>
					</thead>
					
					<tbody>
						<row>
							<entry><link linkend="thread.concepts.Mutex">Mutex</link></entry>
							<entry></entry>
							<entry>
							<para><classname>boost::mutex</classname></para>
							<para><classname>boost::recursive_mutex</classname></para>
							</entry>
						</row>
						<row>
							<entry><link linkend="thread.concepts.TryMutex">TryMutex</link></entry>
							<entry><link linkend="thread.concepts.Mutex">Mutex</link></entry>
							<entry>
								<para><classname>boost::try_mutex</classname></para>
								<para><classname>boost::recursive_try_mutex</classname></para>
							</entry>
						</row>
						<row>
							<entry><link linkend="thread.concepts.TimedMutex">TimedMutex</link></entry>
							<entry><link linkend="thread.concepts.TryMutex">TryMutex</link></entry>
							<entry>
								<para><classname>boost::timed_mutex</classname></para>
								<para><classname>boost::recursive_timed_mutex</classname></para>
							</entry>
						</row>
					</tbody>
				</tgroup>
			</table>
		</section>
		
		<section id="thread.concepts.lock-concepts">
			<title>Lock Concepts</title>

			<para>A lock object provides a safe means for locking and unlocking a mutex
			object (an object whose type is a model of <link
			linkend="thread.concepts.Mutex">Mutex</link> or one of its refinements). In
			other words they are an implementation of the <emphasis>Scoped
			Locking</emphasis> &cite.SchmidtStalRohnertBuschmann; pattern. The <link
			linkend="thread.concepts.ScopedLock">ScopedLock</link>,
			<link linkend="thread.concepts.ScopedTryLock">ScopedTryLock</link>, and 
			<link linkend="thread.concepts.ScopedTimedLock">ScopedTimedLock</link>
			concepts formalize the requirements.</para>
			<para>Lock objects are constructed with a reference to a mutex object and
			typically acquire ownership of the mutex object by setting its state to
			locked. They also ensure ownership is relinquished in the destructor. Lock
			objects also expose functions to query the lock status and to manually lock
			and unlock the mutex object.</para>
			<para>Lock objects are meant to be short lived, expected to be used at block
			scope only. The lock objects are not <link
			linkend="thread.glossary.thread-safe">thread-safe</link>. Lock objects must
			maintain state to indicate whether or not they've been locked and this state
			is not protected by any synchronization concepts. For this reason a lock
			object should never be shared between multiple threads.</para>

			<section id="thread.concepts.Lock">
				<title>Lock Concept</title>
				
				<para>For a Lock type <code>L</code> 
				and an object <code>lk</code> 
				and const object <code>clk</code> of that type, 
				the following expressions must be well-formed
				and have the indicated effects.</para>
				
				<table>
					<title>Lock Expressions</title>
					
					<tgroup cols="2">
						<thead>
							<row>
								<entry>Expression</entry>
								<entry>Effects</entry>
							</row>
						</thead>
						
						<tbody>
							<row>
								<entry><code>(&amp;lk)-&gt;~L();</code></entry>
								<entry><code>if (locked()) unlock();</code></entry>
							</row>
							<row>
								<entry><code>(&amp;clk)-&gt;operator const void*()</code></entry>
								<entry>Returns type void*, non-zero if the associated mutex
								object has been locked by <code>clk</code>, otherwise 0.</entry>
							</row>
							<row>
								<entry><code>clk.locked()</code></entry>
								<entry>Returns a <code>bool</code>, <code>(&amp;clk)-&gt;operator
								const void*() != 0</code></entry>
							</row>
							<row>
								<entry><code>lk.lock()</code></entry>
								<entry>
									<para>Throws <classname>boost::lock_error</classname>
									if <code>locked()</code>.</para>
									
									<para>If the associated mutex object is
									already locked by some other thread, places the current thread in the 
									<link linkend="thread.glossary.thread-state">Blocked</link> state until
									the associated mutex is unlocked, after which the current thread
									is placed in the <link
									linkend="thread.glossary.thread-state">Ready</link> state,
									eventually to be returned to the <link
									linkend="thread.glossary.thread-state">Running</link> state. If
									the associated mutex object is already locked by the same thread
									the behavior is dependent on the <link
									linkend="thread.concepts.locking-strategies">locking
									strategy</link> of the associated mutex object.</para>
									
									<para>Postcondition: <code>locked() == true</code></para>
								</entry>
							</row>
							<row>
								<entry><code>lk.unlock()</code></entry>
								<entry>
									<para>Throws <classname>boost::lock_error</classname>
									if <code>!locked()</code>.</para>
									
									<para>Unlocks the associated mutex.</para>
									
									<para>Postcondition: <code>!locked()</code></para></entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
		
			<section id="thread.concepts.ScopedLock">
				<title>ScopedLock Concept</title>
				
				<para>A ScopedLock is a refinement of <link
				linkend="thread.concepts.Lock">Lock</link>. 
				For a ScopedLock type <code>L</code> 
				and an object <code>lk</code> of that type, 
				and an object <code>m</code> of a type meeting the 
				<link linkend="thread.concepts.Mutex">Mutex</link> requirements, 
				and an object <code>b</code> of type <code>bool</code>, 
				the following expressions must be well-formed 
				and have the indicated effects.</para>
				
				<table>
					<title>ScopedLock Expressions</title>
					
					<tgroup cols="2">
						<thead>
							<row>
								<entry>Expression</entry>
								<entry>Effects</entry>
							</row>
						</thead>
						
						<tbody>
							<row>
								<entry><code>L lk(m);</code></entry>
								<entry>Constructs an object <code>lk</code>, and associates mutex
								object <code>m</code> with it, then calls
								<code>lock()</code></entry>
							</row>
							<row>
								<entry><code>L lk(m,b);</code></entry>
								<entry>Constructs an object <code>lk</code>, and associates mutex
								object <code>m</code> with it, then if <code>b</code>, calls
								<code>lock()</code></entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
		
			<section id="thread.concepts.TryLock">
				<title>TryLock Concept</title>
				
				<para>A TryLock is a refinement of <link
				linkend="thread.concepts.Lock">Lock</link>. 
				For a TryLock type <code>L</code> 
				and an object <code>lk</code> of that type, 
				the following expressions must be well-formed 
				and have the indicated effects.</para>
				
				<table>
					<title>TryLock Expressions</title>
					
					<tgroup cols="2">
						<thead>
							<row>
								<entry>Expression</entry>
								<entry>Effects</entry>
							</row>
						</thead>
						
						<tbody>
							<row>
								<entry><code>lk.try_lock()</code></entry>
								<entry>
									<para>Throws  <classname>boost::lock_error</classname>
									if locked().</para>
									
									<para>Makes a
									non-blocking attempt to lock the associated mutex object,
									returning <code>true</code> if the lock attempt is successful,
									otherwise <code>false</code>. If the associated mutex object is
									already locked by the same thread the behavior is dependent on the
									<link linkend="thread.concepts.locking-strategies">locking
									strategy</link> of the associated mutex object.</para>
								</entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
		
			<section id="thread.concepts.ScopedTryLock">
				<title>ScopedTryLock Concept</title>
				
				<para>A ScopedTryLock is a refinement of <link
				linkend="thread.concepts.TryLock">TryLock</link>. 
				For a ScopedTryLock type <code>L</code> 
				and an object <code>lk</code> of that type, 
				and an object <code>m</code> of a type meeting the 
				<link linkend="thread.concepts.TryMutex">TryMutex</link> requirements, 
				and an object <code>b</code> of type <code>bool</code>, 
				the following expressions must be well-formed 
				and have the indicated effects.</para>
				
				<table>
					<title>ScopedTryLock Expressions</title>
					
					<tgroup cols="2">
						<thead>
							<row>
								<entry>Expression</entry>
								<entry>Effects</entry>
							</row>
						</thead>
						
						<tbody>
							<row>
								<entry><code>L lk(m);</code></entry>
								<entry>Constructs an object <code>lk</code>, and associates mutex
								object <code>m</code> with it, then calls
								<code>try_lock()</code></entry>
							</row>
							<row>
								<entry><code>L lk(m,b);</code></entry>
								<entry>Constructs an object <code>lk</code>, and associates mutex
								object <code>m</code> with it, then if <code>b</code>, calls
								<code>lock()</code></entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
		
			<section id="thread.concepts.TimedLock">
				<title>TimedLock Concept</title>
				
				<para>A TimedLock is a refinement of <link
				linkend="thread.concepts.TryLock">TryLock</link>. 
				For a TimedLock type <code>L</code> 
				and an object <code>lk</code> of that type, 
				and an object <code>t</code> of type <classname>boost::xtime</classname>, 
				the following expressions must be well-formed 
				and have the indicated effects.</para>
				
				<table>
					<title>TimedLock Expressions</title>
					<tgroup cols="2">
						<thead>
							<row>
							<entry>Expression</entry>
							<entry>Effects</entry>
							</row>
						</thead>
						
						<tbody>
							<row>
								<entry><code>lk.timed_lock(t)</code></entry>
								<entry>
									<para>Throws <classname>boost::lock_error</classname>
									if locked().</para>
									
									<para>Makes a blocking attempt
									to lock the associated mutex object, and returns <code>true</code>
									if successful within the specified time <code>t</code>, otherwise
									<code>false</code>. If the associated mutex object is already
									locked by the same thread the behavior is dependent on the <link
									linkend="thread.concepts.locking-strategies">locking
									strategy</link> of the associated mutex object.</para>
								</entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
		
			<section id="thread.concepts.ScopedTimedLock">
				<title>ScopedTimedLock Concept</title>
				
				<para>A ScopedTimedLock is a refinement of <link
				linkend="thread.concepts.TimedLock">TimedLock</link>. 
				For a ScopedTimedLock type <code>L</code> 
				and an object <code>lk</code> of that type, 
				and an object <code>m</code> of a type meeting the 
				<link linkend="thread.concepts.TimedMutex">TimedMutex</link> requirements, 
				and an object <code>b</code> of type <code>bool</code>, 
				and an object <code>t</code> of type <classname>boost::xtime</classname>, 
				the following expressions must be well-formed 
				and have the indicated effects.</para>
				
				<table>
					<title>ScopedTimedLock Expressions</title>
					<tgroup cols="2">
						<thead>
							<row>
							<entry>Expression</entry>
							<entry>Effects</entry>
							</row>
						</thead>
						
						<tbody>
							<row>
								<entry><code>L lk(m,t);</code></entry>
								<entry>Constructs an object <code>lk</code>, and associates mutex
								object <code>m</code> with it, then calls
								<code>timed_lock(t)</code></entry>
							</row>
							<row>
								<entry><code>L lk(m,b);</code></entry>
								<entry>Constructs an object <code>lk</code>, and associates mutex
								object <code>m</code> with it, then if <code>b</code>, calls
								<code>lock()</code></entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
		</section>

		<section id="thread.concepts.lock-models">
			<title>Lock Models</title>
			
			<para>&Boost.Thread; currently supplies twelve models of
			<link linkend="thread.concepts.Lock">Lock</link>
			and its refinements.</para>
			
			<table>
				<title>Lock Models</title>
				
				<tgroup cols="3">
					<thead>
						<row>
							<entry>Concept</entry>
							<entry>Refines</entry>
							<entry>Models</entry>
						</row>
					</thead>
					
					<tbody>
						<row>
							<entry><link linkend="thread.concepts.Lock">Lock</link></entry>
							<entry></entry>
							<entry></entry>
						</row>
						<row>
							<entry><link linkend="thread.concepts.ScopedLock">ScopedLock</link></entry>
							<entry><link linkend="thread.concepts.Lock">Lock</link></entry>
							<entry>
								<para><classname>boost::mutex::scoped_lock</classname></para>
								<para><classname>boost::recursive_mutex::scoped_lock</classname></para>
								
								<para><classname>boost::try_mutex::scoped_lock</classname></para>
								<para><classname>boost::recursive_try_mutex::scoped_lock</classname></para>
								
								<para><classname>boost::timed_mutex::scoped_lock</classname></para>
								<para><classname>boost::recursive_timed_mutex::scoped_lock</classname></para>
							</entry>
						</row>
						<row>
							<entry><link linkend="thread.concepts.TryLock">TryLock</link></entry>
							<entry><link linkend="thread.concepts.Lock">Lock</link></entry>
							<entry></entry>
						</row>
						<row>
							<entry><link linkend="thread.concepts.ScopedTryLock">ScopedTryLock</link></entry>
							<entry><link linkend="thread.concepts.TryLock">TryLock</link></entry>
							<entry>
								<para><classname>boost::try_mutex::scoped_try_lock</classname></para>
								<para><classname>boost::recursive_try_mutex::scoped_try_lock</classname></para>
								
								<para><classname>boost::timed_mutex::scoped_try_lock</classname></para>
								<para><classname>boost::recursive_timed_mutex::scoped_try_lock</classname></para>
							</entry>
						</row>
						<row>
							<entry><link linkend="thread.concepts.TimedLock">TimedLock</link></entry>
							<entry><link linkend="thread.concepts.TryLock">TryLock</link></entry>
							<entry></entry>
						</row>
						<row>
							<entry><link linkend="thread.concepts.ScopedTimedLock">ScopedTimedLock</link></entry>
							<entry><link linkend="thread.concepts.TimedLock">TimedLock</link></entry>
							<entry>
								<para><classname>boost::timed_mutex::scoped_timed_lock</classname></para>
								<para><classname>boost::recursive_timed_mutex::scoped_timed_lock</classname></para>
							</entry>
						</row>
					</tbody>
				</tgroup>
			</table>
		</section>
	</section>

	<section id="thread.concepts.read-write-mutexes">
	<title>Read/Write Mutexes</title>
        <note> Unfortunately it turned out that the current implementation has
            some serious problems. So it was decided not to put this implementation into
            release grade code. Also discussions on the mailing list led to the
            conclusion that the current concepts need to be rethought. In particular
            the schedulings <link linkend="thread.concepts.read-write-scheduling-policies.inter-class">
                Inter-Class Scheduling Policies</link> are deemed unnecessary.
            There seems to be common belief that a fair scheme suffices.
            The following documentation has been retained however, to give
            readers of this document the opportunity to study the original design.
        </note>

        <para>A read/write mutex (short for reader/writer mutual-exclusion) object
		is used to serialize access to a resource shared between multiple 
		threads, where multiple "readers" can share simultaneous access, but 
		"writers" require exclusive access. The
		<link linkend="thread.concepts.ReadWriteMutex">ReadWriteMutex</link> concept, with 
		<link linkend="thread.concepts.TryReadWriteMutex">TryReadWriteMutex</link> and 
		<link linkend="thread.concepts.TimedReadWriteMutex"> TimedReadWriteMutex</link>
		refinements formalize the requirements. A model that implements 
		ReadWriteMutex and its refinements has three states: 
		<emphasis role="bold">read-locked</emphasis>,
		<emphasis role="bold">write-locked</emphasis>, and 
		<emphasis role="bold">unlocked</emphasis>.
		Before reading from a shared resource, a thread 
		<emphasis role="bold">read-locks</emphasis> 
		a &Boost.Thread; read/write mutex object
		(an object whose type is a model of
		<link linkend="thread.concepts.ReadWriteMutex">ReadWriteMutex</link>
		or one of it's refinements), ensuring 
		<link linkend="thread.glossary.thread-safe">thread-safe</link>
		access for reading from the shared resource. Before writing 
		to a shared resource, a thread 
		<emphasis role="bold">write-locks</emphasis> a &Boost.Thread; 
		read/write mutex object
		(an object whose type is a model of
		<link linkend="thread.concepts.ReadWriteMutex">ReadWriteMutex</link>
		or one of it's refinements), ensuring 
		<link linkend="thread.glossary.thread-safe">thread-safe</link>
		access for altering the shared resource. When use of the shared 
		resource is complete, the thread unlocks the mutex object, 
		allowing another thread to acquire the lock and use the shared 
		resource.</para>
		
		<para>Traditional C thread APIs that provide read/write mutex
		primitives (like POSIX threads) expose functions to lock and unlock a
		mutex object. This is dangerous since it's easy to forget to unlock a
		locked mutex. When the flow of control is complex, with multiple
		return points, the likelihood of forgetting to unlock a mutex object
		becomes even greater. When exceptions are thrown, it becomes nearly
		impossible to ensure that the mutex object is unlocked
		properly when using these traditional API's. The result is
		<link linkend="thread.glossary.deadlock">deadlock</link>.</para>
		
		<para>Many C++ threading libraries use a pattern known as <emphasis>Scoped
		Locking</emphasis> &cite.SchmidtStalRohnertBuschmann; to free the
		programmer from the need to explicitly lock and unlock
		read/write mutex objects. With this  pattern, a 
		<link linkend="thread.concepts.read-write-lock-concepts">Read/Write Lock</link>
		concept is employed where the lock object's constructor locks
		the associated read/write mutex object
		and the destructor automatically does the unlocking. The
		&Boost.Thread; library takes this pattern to
		the extreme in that 
		<link linkend="thread.concepts.read-write-lock-concepts">Read/Write Lock</link>
		concepts are the only way to lock and unlock a read/write mutex
		object: lock and unlock functions are not exposed by any
		&Boost.Thread; read/write mutex objects. This helps to
		ensure safe usage patterns, especially when code throws exceptions.</para>
		
		<section id="thread.concepts.read-write-locking-strategies">
			<title>Locking Strategies</title>
			
			<para>Every read/write mutex object follows one of several locking
			strategies. These strategies define the semantics for the locking
			operation when the calling thread already owns a lock on the 
			read/write mutex object.</para>
			
			<section id="thread.concepts.read-write-locking-strategies.recursive">
				<title>Recursive Locking Strategy</title>

				<para>With a recursive locking strategy, when a thread attempts
				to acquire a lock on a read/write mutex object
				for which it already owns a lock, the operation is successful,
				except in the case where a thread holding a read-lock 
				attempts to obtain a write lock, in which case a
				<classname>boost::lock_error</classname> exception will
				be thrown. Note the distinction between a thread, which may have
				multiple locks outstanding on a recursive read/write mutex object,
				and a lock object, which even for a recursive read/write mutex
				object cannot have any of its lock functions called multiple
				times without first calling unlock.</para>
				
				<informaltable>
					<tgroup cols="3">
						<thead>
							<row>
								<entry>Lock Type Held</entry>
								<entry>Lock Type Requested</entry>
								<entry>Action</entry>
							</row>
						</thead>

						<tbody>
							<row> 
								<entry>read-lock</entry>
								<entry>read-lock</entry>
								<entry>Grant the read-lock immediately</entry>
							</row>
							<row> 
								<entry>read-lock</entry>
								<entry>write-lock</entry>
								<entry>If this thread is the only holder of the read-lock,
								grants the write lock immediately. Otherwise throws a
								<classname>boost::lock_error</classname> exception.</entry>
							</row>
							<row> 
								<entry>write-locked</entry>
								<entry>read-lock</entry>
								<entry>Grants the (additional) read-lock immediately.</entry>
							</row>
							<row> 
								<entry>write-locked</entry>
								<entry>write-lock</entry>
								<entry> Grant the write-lock immediately</entry>
							</row>
						</tbody>
					</tgroup>
				</informaltable>
				
				<para>Internally a lock count is maintained and the owning
				thread must unlock the mutex object the same number of times
				that it locked it before the mutex object's state returns
				to unlocked. Since mutex objects in &Boost.Thread; expose
				locking functionality only through lock concepts, a thread
				will always unlock a mutex object the same number of times
				that it locked it. This helps to eliminate a whole set of
				errors typically found in traditional C style thread APIs.
				</para>
				
				<para>&Boost.Thread; does not currently provide any read/write mutex objects 
				that use this strategy.  A successful implementation of this locking strategy
				may require
				<link linkend="thread.concepts.read-write-locking-strategies.thread-identification">thread identification</link>.
				</para>
			</section>
			
			<section id="thread.concepts.read-write-locking-strategies.checked">
				<title>Checked Locking Strategy</title>

				<para>With a checked locking strategy, when a thread attempts
				to acquire a lock on the mutex object for which the thread
				already owns a lock, the operation will fail with some sort of
				error indication, except in the case of multiple read-lock 
				acquisition which is a normal operation for ANY ReadWriteMutex.
				Further, attempts by a thread to unlock a mutex that was not
				locked by the thread will also return some sort of error
				indication. In &Boost.Thread;, an exception of type 
				<classname>boost::lock_error</classname> would be thrown in
				these cases.</para>

				<informaltable>
					<tgroup cols="3">
						<thead>
							<row>
								<entry>Lock Type Held</entry>
								<entry>Lock Type Requested</entry>
								<entry>Action</entry>
							</row>
						</thead>

						<tbody>
							<row> 
								<entry>read-lock</entry>
								<entry>read-lock</entry>
								<entry>Grant the read-lock immediately</entry>
							</row>
							<row> 
								<entry>read-lock</entry>
								<entry>write-lock</entry>
								<entry>Throw <classname>boost::lock_error</classname></entry>
							</row>
							<row> 
								<entry>write-locked</entry>
								<entry>read-lock</entry>
								<entry>Throw <classname>boost::lock_error</classname></entry>
							</row>
							<row> 
								<entry>write-locked</entry>
								<entry>write-lock</entry>
								<entry> Throw <classname>boost::lock_error</classname></entry>
							</row>
						</tbody>
					</tgroup>
				</informaltable>
				
				<para>&Boost.Thread; does not currently provide any read/write mutex objects 
				that use this strategy.  A successful implementation of this locking strategy
				may require
				<link linkend="thread.concepts.read-write-locking-strategies.thread-identification">thread identification</link>.
				</para>
			</section>
			
			<section id="thread.concepts.read-write-locking-strategies.unchecked">
				<title>Unchecked Locking Strategy</title>

				<para>With an unchecked locking strategy, when a thread
				attempts to acquire a lock on the read/write mutex object
				for which the thread already owns a lock, the operation 
				will <link linkend="thread.glossary.deadlock">deadlock</link>.
				In general this locking strategy is less safe than a checked
				or recursive strategy, but it can be a faster strategy and so
				is employed by many libraries.</para>

				<informaltable>
					<tgroup cols="3">
						<thead>
							<row>
								<entry>Lock Type Held</entry>
								<entry>Lock Type Requested</entry>
								<entry>Action</entry>
							</row>
						</thead>

						<tbody>
							<row> 
								<entry>read-lock</entry>
								<entry>read-lock</entry>
								<entry>Grant the read-lock immediately</entry>
							</row>
							<row> 
								<entry>read-lock</entry>
								<entry>write-lock</entry>
								<entry><link linkend="thread.glossary.deadlock">Deadlock</link></entry>
							</row>
							<row> 
								<entry>write-locked</entry>
								<entry>read-lock</entry>
								<entry><link linkend="thread.glossary.deadlock">Deadlock</link></entry>
							</row>
							<row> 
								<entry>write-locked</entry>
								<entry>write-lock</entry>
								<entry><link linkend="thread.glossary.deadlock">Deadlock</link></entry>
							</row>
						</tbody>
					</tgroup>
				</informaltable>
				
				<para>&Boost.Thread; does not currently provide any mutex
				objects that use this strategy.  For ReadWriteMutexes on
				platforms that contain natively recursive synchronization
				primitives, implementing a guaranteed-deadlock can actually
				involve extra work, and would likely require 
				<link linkend="thread.concepts.read-write-locking-strategies.thread-identification">thread identification</link>.
				</para>
  			</section>
			
			<section id="thread.concepts.read-write-locking-strategies.unspecified">
				<title>Unspecified Locking Strategy</title>

				<para>With an unspecified locking strategy, when a thread
				attempts to acquire a lock on a read/write mutex object for
				which the thread already owns a lock, the operation results 
				in <link linkend="thread.glossary.undefined-behavior">undefined behavior</link>.
				When a read/write mutex object has an unspecified locking 
				strategy the programmer must assume that the read/write mutex
				object instead uses an unchecked strategy as the worse case,
				although some platforms may exhibit a mix of unchecked and
				recursive behavior.</para>

				<informaltable>
					<tgroup cols="3">
						<thead>
							<row>
								<entry>Lock Type Held</entry>
								<entry>Lock Type Requested</entry>
								<entry>Action</entry>
							</row>
						</thead>

						<tbody>
							<row> 
								<entry>read-lock</entry>
								<entry>read-lock</entry>
								<entry>Grant the read-lock immediately</entry>
							</row>
							<row> 
								<entry>read-lock</entry>
								<entry>write-lock</entry>
								<entry> 
								<link linkend="thread.glossary.undefined-behavior">Undefined</link>, but generally <link linkend="thread.glossary.deadlock">deadlock</link>
							</entry>
							</row>
							<row> 
								<entry>write-locked</entry>
								<entry>read-lock</entry>
								<entry><link linkend="thread.glossary.undefined-behavior">Undefined</link>, but generally <link linkend="thread.glossary.deadlock">deadlock</link></entry>
							</row>
							<row> 
								<entry>write-locked</entry>
								<entry>write-lock</entry>
								<entry><link linkend="thread.glossary.undefined-behavior">Undefined</link>, but generally <link linkend="thread.glossary.deadlock">deadlock</link></entry>
							</row>
						</tbody>
					</tgroup>
				</informaltable>

				<para>In general a read/write mutex object with an unspecified
				locking strategy is unsafe, and it requires programmer discipline
				to use the read/write mutex object properly. However, this strategy
				allows an implementation to be as fast as possible with no restrictions 
				on its implementation. This is especially true for portable implementations
				that wrap the native threading support of a platform. For this reason, the
				classes 
				<classname>read_write_mutex</classname>,
				<classname>try_read_write_mutex</classname>, and
				<classname>timed_read_write_mutex</classname>
				use this locking strategy despite the lack of safety.</para>
			</section>
			
			<section id="thread.concepts.read-write-locking-strategies.thread-identification">
				<title>Thread Identification</title>

				<para>ReadWriteMutexes can support specific Locking Strategies 
				(recursive and checked) which help to detect and protect against
				self-deadlock.  Self-deadlock can occur when a holder of a locked
				ReadWriteMutex attempts to obtain another lock.  Given an
				implemention <emphasis>I</emphasis> which is susceptible to
				self-deadlock but otherwise correct and efficient, a recursive or
				checked implementation <emphasis>Ir</emphasis> or 
				<emphasis>Ic</emphasis> can use the same basic implementation,
				but make special checks against self-deadlock by tracking the
				identities of thread(s) currently holding locks.  This approach 
				makes deadlock detection othrogonal to the basic ReadWriteMutex
				implementaion.</para>
				
				<para>Alternatively, a different basic implementation for 
				ReadWriteMutex concepts, 
				<emphasis>I'</emphasis> (I-Prime) may exist which uses recursive
				or checked versions of synchronization primitives to produce
				a recursive or checked ReadWriteMutex while still providing
				flexibility in terms of Scheduling Policies. </para>
				
				<para>Please refer to the &Boost.Thread;
				<link linkend="thread.concepts.read-write-mutex-concepts">read/write mutex concept</link> 
				documentation for a discussion of locking strategies.
				The read/write mutex supports only the
				<link linkend="thread.concepts.read-write-locking-strategies.unspecified">unspecified</link>
				locking strategy. ReadWriteMutexes are parameterized on a
				Mutex type which they use to control write-locking 
				and access to internal state.</para>
			</section>
			
			<section id="thread.concepts.read-write-locking-strategies.promotion">
				<title>Lock Promotion</title>

				<para>ReadWriteMutexes can support lock promotion, where a
				mutex which is in the read-locked state transitions to a
				write-locked state without releasing the lock. Lock
				promotion can be tricky to implement; for instance,
				extra care must be taken to ensure that only one thread holding a
				read-lock can block awaiting promotion at any given time.  If
				more than one read-lock holder is allowed to enter a blocked
				state while waiting to be promoted, deadlock will result since
				both threads will be waiting for the other to release their read-lock.
				</para>
				
				<para>Currently, &Boost.Thread; supports lock promotion
				through <code>promote()</code>, <code>try_promote()</code>,
				and <code>timed_promote()</code> operations.</para>
			</section>
			
			<section id="thread.concepts.read-write-locking-strategies.demotion">
				<title>Lock Demotion</title>

				<para>ReadWriteMutexes can support lock demotion, where a
				mutex which is in the write-locked state transitions to a
				read-locked state without releasing the lock.
				Since by definition only one thread at a time may hold
				a write-lock, the problem with deadlock that can occur
				during lock promotion is not a problem for lock
				demotion.</para>
				
				<para>Currently, &Boost.Thread; supports lock demotion
				through <code>demote()</code>, <code>try_demote()</code>,
				and <code>timed_demote()</code> operations.</para>
			</section>
		</section>
		
		<section id="thread.concepts.read-write-scheduling-policies">
			<title>Scheduling Policies</title>
			
			<para>Every read/write mutex object follows one of several scheduling
			policies. These policies define the semantics when the mutex object
			is unlocked and there is more than one thread waiting to acquire a
			lock. In other words, the policy defines which waiting thread shall
			acquire the lock. For a read/write mutex, it is particularly important
			to define the behavior when threads are requesting both read and
			write access simultaneously. This will be referred to as "inter-class 
			scheduling" because it describes the scheduling between two
			classes of threads (those waiting for a read lock and those
			waiting for a write lock).</para>
			
			<para>For some types of inter-class scheduling, an "intra-class"
			scheduling policy can also be defined that will describe the order
			in which waiting threads of the same class (i.e., those
			waiting for the same type of lock) will acquire the thread.
			</para>
			
			<section id="thread.concepts.read-write-scheduling-policies.inter-class">
				<title>Inter-Class Scheduling Policies</title>
				
				<section id="thread.concepts.read-write-scheduling-policies.reader-priority">	
					<title>ReaderPriority</title>
					
					<para>With ReaderPriority scheduling, any pending request for
					a read-lock will have priority over a pending request for a
					write-lock, irrespective of the current lock state of the 
					read/write mutex, and irrespective of the relative order
					that the pending requests arrive.</para>

					<informaltable>
						<tgroup cols="3">
							<thead>
								<row>
									<entry>Current mutex state</entry>
									<entry>Request Type</entry>
									<entry>Action</entry>
								</row>
							</thead>

							<tbody>
								<row> 
									<entry>unlocked</entry>
									<entry>read-lock</entry>
									<entry>Grant the read-lock immediately</entry>
								</row>
								<row> 
									<entry>read-locked</entry>
									<entry>read-lock</entry>
									<entry>Grant the additional read-lock immediately.</entry>
								</row>
								<row> 
									<entry>write-locked</entry>
									<entry>read-lock</entry>
									<entry>Wait to acquire the lock until the thread
									holding the write-lock releases its lock (or until
									the specified time, if any). A
									read-lock will be granted to all pending readers 
									before any other thread can acquire a write-lock.
									<para>TODO: try-lock, timed-lock.</para>
									</entry>
								</row>
								<row> 
									<entry>unlocked</entry>
									<entry>write-lock</entry>
									<entry>Grant the write-lock immediately, if and
									only if there are no pending read-lock requests.
									<para>TODO: try-lock, timed-lock.</para>
									</entry>
								</row>
								<row> 
									<entry>read-locked</entry>
									<entry>write-lock</entry>
									<entry> Wait to acquire the lock until all
									threads holding read-locks release their locks 
									<emphasis role="bold">AND</emphasis> no requests
									for read-locks exist. If other write-lock
									requests exist, the lock is granted in accordance
									with the intra-class scheduling policy.
									<para>TODO: try-lock, timed-lock.</para>
									</entry>
								</row>
								<row> 
									<entry>write-locked</entry>
									<entry>write-lock</entry>
									<entry>Wait to acquire the lock until the thread
									holding the write-lock releases its lock
									<emphasis role="bold">AND</emphasis> no requests
									for read-locks exist. If other write-lock
									requests exist, the lock is granted in accordance
									with the intra-class scheduling policy.
									<para>TODO: try-lock, timed-lock.</para>
									</entry>
								</row>
								<row> 
									<entry>read-locked</entry>
									<entry>promote</entry>
									<entry><para>TODO</para></entry>
								</row>
								<row> 
									<entry>write-locked</entry>
									<entry>demote</entry>
									<entry><para>TODO</para></entry>
								</row>
							</tbody>
						</tgroup>
					</informaltable>
				</section>

				<section id="thread.concepts.read-write-scheduling-policies.writer-priority">
					<title>WriterPriority</title>
					
					<para>With WriterPriority scheduling, any pending request
					for a write-lock will have priority over a pending request
					for a read-lock, irrespective of the current lock state 
					of the read/write mutex, and irrespective of the relative
					order that the pending requests arrive.</para>
					
					<informaltable>
						<tgroup cols="3">
							<thead>
								<row>
									<entry>Current mutex state</entry>
									<entry>Request Type</entry>
									<entry>Action</entry>
								</row>
							</thead>

							<tbody>
								<row> 
									<entry>unlocked</entry>
									<entry>read-lock</entry>
									<entry>Grant the read-lock immediately.</entry>
								</row>
								<row> 
									<entry>read-locked</entry>
									<entry>read-lock</entry>
									<entry>Grant the additional read-lock immediately, 
									<emphasis role="bold">IF</emphasis> no outstanding
									requests for a write-lock exist; otherwise TODO.
									<para>TODO: try-lock, timed-lock.</para>
									</entry>
								</row>
								<row> 
									<entry>write-locked</entry>
									<entry>read-lock</entry>
									<entry> Wait to acquire the lock until the
									thread holding the write-lock 
									releases its lock. The read lock will be granted
									once no other outstanding write-lock requests
									exist.
									<para>TODO: try-lock, timed-lock.</para>
									</entry>
								</row>
								<row> 
									<entry>unlocked</entry>
									<entry>write-lock</entry>
									<entry>Grant the write-lock immediately.</entry>
								</row>
								<row> 
									<entry>read-locked</entry>
									<entry>write-lock</entry>
									<entry>Wait to acquire the lock until all
									threads holding read-locks release their locks.
									If other write-lock requests exist, the lock
									is granted in accordance with the intra-class
									scheduling policy. This request will be granted
									before any new read-lock requests are granted.
									<para>TODO: try-lock, timed-lock.</para>
									</entry>
								</row>
								<row> 
									<entry>write-locked</entry>
									<entry>write-lock</entry>
									<entry>Wait to acquire the lock until the thread
									holding the write-lock releases its lock. If
									other write-lock requests exist, the lock is
									granted in accordance with the intra-class
									scheduling policy. This request will be granted
									before any new read-lock requests are granted.
									<para>TODO: try-lock, timed-lock.</para>
									</entry>
								</row>
								<row> 
									<entry>read-locked</entry>
									<entry>promote</entry>
									<entry><para>TODO</para></entry>
								</row>
								<row> 
									<entry>write-locked</entry>
									<entry>demote</entry>
									<entry><para>TODO</para></entry>
								</row>
							</tbody>
						</tgroup>
					</informaltable>
				</section>
				
				<section id="thread.concepts.read-write-scheduling-policies.alternating-many-reads">
					<title>AlternatingPriority/ManyReads</title>
					
					<para>With AlternatingPriority/ManyReads scheduling, reader
					or writer starvation is avoided by alternatively granting read
					or write access when pending requests exist for both types of
					locks. Outstanding read-lock requests are treated as a group
					when it is the "readers' turn"</para>
					
					<informaltable>
						<tgroup cols="3">
							<thead>
								<row>
									<entry>Current mutex state</entry>
									<entry>Request Type</entry>
									<entry>Action</entry>
								</row>
							</thead>

							<tbody>
								<row> 
									<entry>unlocked</entry>
									<entry>read-lock</entry>
									<entry>Grant the read-lock immediately.</entry>
								</row>
								<row> 
									<entry>read-locked</entry>
									<entry>read-lock</entry>
									<entry>Grant the additional read-lock immediately,
									<emphasis role="bold">IF</emphasis> no outstanding 
									requests for a write-lock exist. If outstanding
									write-lock requests exist, this lock will not
									be granted until at least one of the 
									write-locks is granted and released. If other
									read-lock requests exist, all read-locks will be
									granted as a group.
									<para>TODO: try-lock, timed-lock.</para>
									</entry>
								</row>
								<row> 
									<entry>write-locked</entry>
									<entry>read-lock</entry>
									<entry> Wait to acquire the lock until the thread
									holding the write-lock releases its lock. If other
									outstanding write-lock requests exist, they will
									have to wait until all current read-lock requests
									are serviced.
									<para>TODO: try-lock, timed-lock.</para>
									</entry>
								</row>
								<row> 
									<entry>unlocked</entry>
									<entry>write-lock</entry>
									<entry>Grant the write-lock immediately.</entry>
								</row>
								<row> 
									<entry>read-locked</entry>
									<entry>write-lock</entry>
									<entry> 
									<para>Wait to acquire the lock until all threads
									holding read-locks release their locks.</para>
									
									<para>If other write-lock requests exist, this
									lock will be granted to one of them in accordance
									with the intra-class scheduling policy.</para>
									
									<para>TODO: try-lock, timed-lock.</para>
									</entry>
								</row>
								<row> 
									<entry>write-locked</entry>
									<entry>write-lock</entry>
									<entry>Wait to acquire the lock until the thread
									holding the write-lock releases its lock.  If
									other outstanding read-lock requests exist, this
									lock will not be granted until all of the
									currently waiting read-locks are granted and
									released. If other write-lock requests exist,
									this lock will be granted in accordance with the
									intra-class scheduling policy.
									<para>TODO: try-lock, timed-lock.</para>
									</entry>
								</row>
								<row> 
									<entry>read-locked</entry>
									<entry>promote</entry>
									<entry><para>TODO</para></entry>
								</row>
								<row> 
									<entry>write-locked</entry>
									<entry>demote</entry>
									<entry><para>TODO</para></entry>
								</row>
							</tbody>
						</tgroup>
					</informaltable>
				</section>
				
				<section id="thread.concepts.read-write-scheduling-policies.alternating-single-read">
					<title>AlternatingPriority/SingleRead</title>
					
					<para>With AlternatingPriority/SingleRead scheduling, reader
					or writer starvation is avoided by alternatively granting read
					or write access when pending requests exist for both types of
					locks. Outstanding read-lock requests are services one at a
					time when it is the "readers' turn"</para>

					<informaltable>
						<tgroup cols="3">
							<thead>
								<row>
									<entry>Current mutex state</entry>
									<entry>Request Type</entry>
									<entry>Action</entry>
								</row>
							</thead>

							<tbody>
								<row> 
									<entry>unlocked</entry>
									<entry>read-lock</entry>
									<entry>Grant the read-lock immediately.</entry>
								</row>
								<row> 
									<entry>read-locked</entry>
									<entry>read-lock</entry>
									<entry>Grant the additional read-lock immediately,
									<emphasis role="bold">IF</emphasis> no outstanding 
									requests for a write-lock exist. If outstanding
									write-lock requests exist, this lock will not
									be granted until at least one of the write-locks
									is granted and released.
									<para>TODO: try-lock, timed-lock.</para>
									</entry>
								</row>
								<row> 
									<entry>write-locked</entry>
									<entry>read-lock</entry>
									<entry> 
									<para>Wait to acquire the lock until the thread
									holding the write-lock releases its lock.</para>
									<para>If other outstanding write-lock requests
									exist, exactly one read-lock request will be
									granted before the next write-lock is granted.
									</para>
									<para>TODO: try-lock, timed-lock.</para>
									</entry>
								</row>
								<row> 
									<entry>unlocked</entry>
									<entry>write-lock</entry>
									<entry>Grant the write-lock immediately.</entry>
								</row>
								<row> 
									<entry>read-locked</entry>
									<entry>write-lock</entry>
									<entry> 
									<para>Wait to acquire the lock until all
									threads holding read-locks release their 
									locks.</para>
									
									<para>If other write-lock requests exist,
									this lock will be granted to one of them
									in accordance with the intra-class
									scheduling policy.</para></entry>
									
									<para>TODO: try-lock, timed-lock.</para>
								</row>
								<row> 
									<entry>write-locked</entry>
									<entry>write-lock</entry>
									<entry>Wait to acquire the lock until the
									thread holding the write-lock releases its
									lock.  If other outstanding read-lock requests
									exist, this lock can not be granted until
									exactly one read-lock request is granted and
									released. If other write-lock requests exist,
									this lock will be granted in accordance with
									the intra-class scheduling policy.
									<para>TODO: try-lock, timed-lock.</para>
									</entry>
								</row>
								<row> 
									<entry>read-locked</entry>
									<entry>promote</entry>
									<entry><para>TODO</para></entry>
								</row>
								<row> 
									<entry>write-locked</entry>
									<entry>demote</entry>
									<entry><para>TODO</para></entry>
								</row>
							</tbody>
						</tgroup>
					</informaltable>
				</section>
			</section>
			
			<section id="thread.concepts.read-write-scheduling-policies.intra-class">
				<title>Intra-Class Scheduling Policies</title>
				
				<para>Please refer to 
				<xref linkend="thread.concepts.sheduling-policies" />
				for a discussion of mutex scheduling policies, which are identical to 
				read/write mutex intra-class scheduling policies.</para>
				
				<para>For threads waiting to obtain write-locks, the read/write mutex
				supports only the 
				<link linkend="thread.concepts.unspecified-scheduling-policy">Unspecified</link>
				intra-class scheduling policy. That is, given a set of threads
				waiting for write-locks, the order, relative to one another, in
				which they receive the write-lock is unspecified.</para>
				
				<para>For threads waiting to obtain read-locks, the read/write mutex
				supports only the 
				<link linkend="thread.concepts.unspecified-scheduling-policy">Unspecified</link>
				intra-class scheduling policy. That is, given a set of threads
				waiting for read-locks, the order, relative to one another, in
				which they receive the read-lock is unspecified.</para>
			</section>
		</section>

		<section id="thread.concepts.read-write-mutex-concepts">
			<title>Mutex Concepts</title>
			
			<section id="thread.concepts.ReadWriteMutex">
				<title>ReadWriteMutex Concept</title>
				
				<para>A ReadWriteMutex object has three states: read-locked,
				write-locked, and unlocked. ReadWriteMutex object state can
				only be determined by a lock object meeting the appropriate lock concept
				requirements and constructed for the ReadWriteMutex object.</para>
				
				<para>A ReadWriteMutex is 
				<ulink url="../../libs/utility/utility.htm#Class%20noncopyable">NonCopyable</ulink>.
				</para>
				
				<para>For a ReadWriteMutex type <code>M</code>, 
				and an object <code>m</code> of that type, 
				the following expressions must be well-formed 
				and have the indicated effects.</para>
				
				<table>
					<title>ReadWriteMutex Expressions</title>
					
					<tgroup cols="2">
						<thead>
							<row>
								<entry>Expression</entry>
								<entry>Effects</entry>
							</row>
						</thead>

						<tbody>
							<row> 
								<entry><code>M m;</code></entry>
								<entry>Constructs a read/write mutex object <code>m</code>.
								Post-condition: <code>m</code> is unlocked.</entry>
							</row>
							<row> 
								<entry><code>(&amp;m)-&gt;~M();</code></entry>
								<entry>Precondition: <code>m</code> is unlocked. 
								Destroys a read/write mutex object <code>m</code>.
								</entry>
							</row>
							<row> 
								<entry><code>M::scoped_read_write_lock</code></entry>
								<entry>A type meeting the 
								<link linkend="thread.concepts.ScopedReadWriteLock">ScopedReadWriteLock</link>
								requirements. </entry>
							</row>
							<row> 
								<entry><code>M::scoped_read_lock</code></entry>
								<entry>A type meeting the 
								<link linkend="thread.concepts.ScopedLock">ScopedLock</link>
								requirements. </entry>
							</row>
							<row> 
								<entry><code>M::scoped_write_lock</code></entry>
								<entry>A type meeting the 
								<link linkend="thread.concepts.ScopedLock">ScopedLock</link>
								requirements. </entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
			
			<section id="thread.concepts.TryReadWriteMutex">
				<title>TryReadWriteMutex Concept</title>
				
				<para>A TryReadWriteMutex is a refinement of
				<link linkend="thread.concepts.ReadWriteMutex">ReadWriteMutex</link>.
				For a TryReadWriteMutex type <code>M</code> 
				and an object <code>m</code> of that type,
				the following expressions must be well-formed 
				and have the indicated effects.</para>
				
				<table>
					<title>TryReadWriteMutex Expressions</title>
					
					<tgroup cols="2">
						<thead>
							<row>
								<entry>Expression</entry>
								<entry>Effects</entry>
							</row>
						</thead>

						<tbody>
							<row> 
								<entry><code>M::scoped_try_read_write_lock</code></entry>
								<entry>A type meeting the 
								<link linkend="thread.concepts.ScopedTryReadWriteLock">ScopedTryReadWriteLock</link>
								requirements.</entry>
							</row>
							<row> 
								<entry><code>M::scoped_try_read_lock</code></entry>
								<entry>A type meeting the 
								<link linkend="thread.concepts.ScopedTryLock">ScopedTryLock</link>
								requirements.</entry>
							</row>
							<row> 
								<entry><code>M::scoped_try_write_lock</code></entry>
								<entry>A type meeting the 
								<link linkend="thread.concepts.ScopedTryLock">ScopedTryLock</link>
								requirements.</entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
			
			<section id="thread.concepts.TimedReadWriteMutex">
				<title>TimedReadWriteMutex Concept</title>
				
				<para>A TimedReadWriteMutex is a refinement of
				<link linkend="thread.concepts.TryReadWriteMutex">TryReadWriteMutex</link>.
				For a TimedReadWriteMutex type <code>M</code> 
				and an object <code>m</code> of that type
				the following expressions must be well-formed 
				and have the indicated effects.</para>
				
				<table>
					<title>TimedReadWriteMutex Expressions</title>
					
					<tgroup cols="2">
						<thead>
							<row>
								<entry>Expression</entry>
								<entry>Effects</entry>
							</row>
						</thead>

						<tbody>
							<row> 
								<entry><code>M::scoped_timed_read_write_lock</code></entry>
								<entry>A type meeting the 
								<link linkend="thread.concepts.ScopedTimedReadWriteLock">ScopedTimedReadWriteLock</link> 
								requirements.</entry>
							</row>
							<row> 
								<entry><code>M::scoped_timed_read_lock</code></entry>
								<entry>A type meeting the 
								<link linkend="thread.concepts.ScopedTimedLock">ScopedTimedLock</link> 
								requirements.</entry>
							</row>
							<row> 
								<entry><code>M::scoped_timed_write_lock</code></entry>
								<entry>A type meeting the 
								<link linkend="thread.concepts.ScopedTimedLock">ScopedTimedLock</link> 
								requirements.</entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
		</section>
		
		<section id="thread.concepts.read-write-mutex-models">
			<title>Mutex Models</title>
			
			<para>&Boost.Thread; currently supplies three models of
			<link linkend="thread.concepts.ReadWriteMutex">ReadWriteMutex</link>
			and its refinements.</para>
			
			<table>
				<title>Mutex Models</title>
				
				<tgroup cols="3">
					<thead>
						<row>
							<entry>Concept</entry>
							<entry>Refines</entry>
							<entry>Models</entry>
						</row>
					</thead>

					<tbody>
						<row> 
							<entry><link linkend="thread.concepts.ReadWriteMutex">ReadWriteMutex</link></entry>
							<entry></entry>
							<entry><classname>boost::read_write_mutex</classname></entry>
						</row>
						<row> 
							<entry><link linkend="thread.concepts.TryReadWriteMutex">TryReadWriteMutex</link></entry>
							<entry><link linkend="thread.concepts.ReadWriteMutex">ReadWriteMutex</link></entry>
							<entry><classname>boost::try_read_write_mutex</classname></entry>
						</row>
						<row> 
							<entry><link linkend="thread.concepts.TimedReadWriteMutex">TimedReadWriteMutex</link></entry>
							<entry><link linkend="thread.concepts.TryReadWriteMutex">TryReadWriteMutex</link></entry>
							<entry><classname>boost::timed_read_write_mutex</classname></entry>
						</row>
					</tbody>
				</tgroup>
			</table>
		</section>
				
		<section id="thread.concepts.read-write-lock-concepts">
			<title>Lock Concepts</title>

			<para>A read/write lock object provides a safe means for locking
			and unlocking a read/write mutex object (an object whose type is
			a model of 
			<link linkend="thread.concepts.ReadWriteMutex">ReadWriteMutex</link> 
			or one of its refinements). In other words they are an
			implementation of the <emphasis>Scoped Locking</emphasis>
			&cite.SchmidtStalRohnertBuschmann; pattern. The 
			<link linkend="thread.concepts.ScopedReadWriteLock">ScopedReadWriteLock</link>, 
			<link linkend="thread.concepts.ScopedTryReadWriteLock">ScopedTryReadWriteLock</link>, and 
			<link linkend="thread.concepts.ScopedTimedReadWriteLock">ScopedTimedReadWriteLock</link>
			concepts formalize the requirements.</para>
			
			<para>Read/write lock objects are constructed with a reference to a
			read/write mutex object and typically acquire ownership of the 
			read/write mutex object by setting its state to locked. They also
			ensure ownership is relinquished in the destructor. Lock objects
			also expose functions to query the lock status and to manually lock
			and unlock the read/write mutex object.</para>
			
			<para>Read/write lock objects are meant to be short lived, expected
			to be used at block scope only. The read/write lock objects are not 
			<link linkend="thread.glossary.thread-safe">thread-safe</link>.
			Read/write lock objects must maintain state to indicate whether or
			not they've been locked and this state is not protected by any
			synchronization concepts. For this reason a read/write lock object
			should never be shared between multiple threads.</para>
			
			<section id="thread.concepts.ReadWriteLock">
				<title>ReadWriteLock Concept</title>
				
				<para>For a read/write lock type <code>L</code>
				and an object <code>lk</code> 
				and const object <code>clk</code> of that type,
				the following expressions must be well-formed
				and have the indicated effects.</para>
				
				<table>
					<title>ReadWriteLock Expressions</title>
				
					<tgroup cols="2">
						<thead>
							<row>
								<entry>Expression</entry>
								<entry>Effects</entry>
							</row>
						</thead>
						
						<tbody>
							<row>
								<entry><code>(&amp;lk)-&gt;~L();</code></entry>
								<entry><code>if (locked()) unlock();</code></entry>
							</row>
							<row>
								<entry><code>(&amp;clk)-&gt;operator const void*()</code></entry>
								<entry>Returns type void*, non-zero if the associated read/write
								mutex object has been either read-locked or write-locked by 
								<code>clk</code>, otherwise 0.</entry>
							</row>
							<row>
								<entry><code>clk.locked()</code></entry>
								<entry>Returns a <code>bool</code>, <code>(&amp;clk)-&gt;operator
								const void*() != 0</code></entry>
							</row>
							<row>
								<entry><code>clk.state()</code></entry>
								<entry>Returns an enumeration constant of type <code>read_write_lock_state</code>:
								<code>read_write_lock_state::read_locked</code> if the associated read/write mutex object has been
								read-locked by <code>clk</code>, <code>read_write_lock_state::write_locked</code> if it
								has been write-locked by <code>clk</code>, and <code>read_write_lock_state::unlocked</code>
								if has not been locked by <code>clk</code>.</entry>
							</row>
							<row>
								<entry><code>clk.read_locked()</code></entry>
								<entry>Returns a <code>bool</code>, <code>(&amp;clk)-&gt;state() == read_write_lock_state::read_locked</code>.</entry>
							</row>
							<row>
								<entry><code>clk.write_locked()</code></entry>
								<entry>Returns a <code>bool</code>, <code>(&amp;clk)-&gt;state() == read_write_lock_state::write_locked</code>.</entry>
							</row>
							<row>
								<entry><code>lk.read_lock()</code></entry>
								<entry>
									<para>Throws <classname>boost::lock_error</classname> 
									if <code>locked()</code>.</para>
									
									<para>If the associated read/write mutex
									object is already read-locked by some other
									thread, the effect depends on the
									<link linkend="thread.concepts.read-write-scheduling-policies.inter-class">inter-class scheduling policy</link>
									of the associated read/write mutex:
									either immediately obtains an additional
									read-lock on the associated read/write
									mutex, or places the current thread in the
									<link linkend="thread.glossary.thread-state">Blocked</link>
									state until the associated read/write mutex
									is unlocked, after which the current thread
									is placed in the 
									<link linkend="thread.glossary.thread-state">Ready</link>
									state, eventually to be returned to the 
									<link linkend="thread.glossary.thread-state">Running</link>
									state.</para>
									
									<para>If the associated read/write mutex
									object is already write-locked by some other
									thread, places the current thread in the
									<link linkend="thread.glossary.thread-state">Blocked</link>
									state until the associated read/write mutex
									is unlocked, after which the current thread
									is placed in the 
									<link linkend="thread.glossary.thread-state">Ready</link>
									state, eventually to be returned to the
									<link linkend="thread.glossary.thread-state">Running</link>
									state.</para>

									<para>If the associated read/write mutex
									object is already locked by the same thread
									the behavior is dependent on the
									<link linkend="thread.concepts.read-write-locking-strategies">locking strategy</link>
									of the associated read/write mutex object.
									</para>
									
									<para>Postcondition: <code>state() == read_write_lock_state::read_locked</code></para>
								</entry>
							</row>
							<row>
								<entry><code>lk.write_lock()</code></entry>

								<entry>
									<para>Throws <classname>boost::lock_error</classname> 
									if <code>locked()</code>.</para>
									
									<para>If the associated read/write mutex
									object is already locked by some other
									thread, places the current thread in the
									<link linkend="thread.glossary.thread-state">Blocked</link>
									state until the associated read/write mutex
									is unlocked, after which the current thread
									is placed in the 
									<link linkend="thread.glossary.thread-state">Ready</link>
									state, eventually to be returned to the
									<link linkend="thread.glossary.thread-state">Running</link>
									state.</para>

									<para>If the associated read/write mutex
									object is already locked by the same thread
									the behavior is dependent on the
									<link linkend="thread.concepts.read-write-locking-strategies">locking strategy</link>
									of the associated read/write mutex object.
									</para>
									
									<para>Postcondition: <code>state() == read_write_lock_state::write_locked</code></para>
								</entry>
							</row>
							<row>
								<entry><code>lk.demote()</code></entry>
								<entry>
									<para>Throws <classname>boost::lock_error</classname>
									if <code>state() != read_write_lock_state::write_locked</code>.</para>
									
									<para>Converts the lock held on the associated read/write mutex
									object from a write-lock to a read-lock without releasing
									the lock.</para>
									
									<para>Postcondition: <code>state() == read_write_lock_state::read_locked</code></para>
								</entry>
							</row>
							<row>
								<entry><code>lk.promote()</code></entry>
								<entry>
									<para>Throws <classname>boost::lock_error</classname>
									if <code>state() != read_write_lock_state::read_locked</code>
									or if the lock cannot be promoted because another lock
									on the same mutex is already waiting to be promoted.</para>
									
									<para>Makes a blocking attempt to convert the lock held on the associated
									read/write mutex object from a read-lock to a write-lock without releasing
									the lock.</para>
								</entry>
							</row>
							<row>
								<entry><code>lk.unlock()</code></entry>
								<entry>
									<para>Throws <classname>boost::lock_error</classname>
									if <code>!locked()</code>.</para>
									
									<para>Unlocks the associated read/write mutex.</para>
									
									<para>Postcondition: <code>!locked()</code></para>
								</entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
			
			<section id="thread.concepts.ScopedReadWriteLock">
				<title>ScopedReadWriteLock Concept</title>
				
				<para>A ScopedReadWriteLock is a refinement of 
				<link linkend="thread.concepts.ReadWriteLock">ReadWriteLock</link>. 
				For a ScopedReadWriteLock type <code>L</code> 
				and an object <code>lk</code> of that type,
				and an object <code>m</code> of a type meeting the 
				<link linkend="thread.concepts.ReadWriteMutex">ReadWriteMutex</link> requirements,
				and an object <code>s</code> of type <code>read_write_lock_state</code>,
				the following expressions must be well-formed 
				and have the indicated effects.</para>
				
				<table>
					<title>ScopedReadWriteLock Expressions</title>
					
					<tgroup cols="2">
						<thead>
							<row>
								<entry>Expression</entry>
								<entry>Effects</entry>
							</row>
						</thead>
						
						<tbody>
							<row>
								<entry><code>L lk(m,s);</code></entry>
								<entry>Constructs an object <code>lk</code> and associates read/write mutex
								object <code>m</code> with it, then: if <code>s == read_write_lock_state::read_locked</code>, calls
								<code>read_lock()</code>; if <code>s==read_write_lock_state::write_locked</code>,
								calls <code>write_lock()</code>.</entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
			
			<section id="thread.concepts.TryReadWriteLock">
				<title>TryReadWriteLock Expressions</title>
				
				<para>A TryReadWriteLock is a refinement of 
				<link linkend="thread.concepts.ReadWriteLock">ReadWriteLock</link>.
				For a TryReadWriteLock type <code>L</code>
				and an object <code>lk</code> of that type,
				the following expressions must be well-formed
				and have the indicated effects.</para>
				
				<table>
					<title>TryReadWriteLock Expressions</title>
					
					<tgroup cols="2">
						<thead>
							<row>
								<entry>Expression</entry>
								<entry>Effects</entry>
							</row>
						</thead>
						
						<tbody>
							<row>
								<entry><code>lk.try_read_lock()</code></entry>
								<entry>
									<para>Throws <classname>boost::lock_error</classname>
									if locked().</para>
								
									<para>Makes a non-blocking attempt to read-lock the associated read/write
									mutex object, returning <code>true</code> if the attempt is successful,
									otherwise <code>false</code>. If the associated read/write mutex object is
									already locked by the same thread the behavior is dependent on the
									<link linkend="thread.concepts.locking-strategies">locking
									strategy</link> of the associated read/write mutex object.</para>
								</entry>
							</row>
							<row>
								<entry><code>lk.try_write_lock()</code></entry>
								<entry>
									<para>Throws <classname>boost::lock_error</classname>
									if locked().</para>
									
									<para>Makes a non-blocking attempt to write-lock the associated read/write
									mutex object, returning <code>true</code> if the attempt is successful,
									otherwise <code>false</code>. If the associated read/write mutex object is
									already locked by the same thread the behavior is dependent on the
									<link linkend="thread.concepts.locking-strategies">locking
									strategy</link> of the associated read/write mutex object.</para>
								</entry>
							</row>
							<row>
								<entry><code>lk.try_demote()</code></entry>
								<entry>
									<para>Throws <classname>boost::lock_error</classname>
									if <code>state() != read_write_lock_state::write_locked</code>.</para> 
									
									<para>Makes a non-blocking attempt to convert the lock held on the associated
									read/write mutex object from a write-lock to a read-lock without releasing
									the lock, returning <code>true</code> if the attempt is successful,
									otherwise <code>false</code>.</para>
								</entry>
							</row>
							<row>
								<entry><code>lk.try_promote()</code></entry>
								<entry>
									<para>Throws <classname>boost::lock_error</classname>
									if <code>state() != read_write_lock_state::read_locked</code>.</para>
									
									<para>Makes a non-blocking attempt to convert the lock held on the associated
									read/write mutex object from a read-lock to a write-lock without releasing
									the lock, returning <code>true</code> if the attempt is successful,
									otherwise <code>false</code>.</para>
								</entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
			
			<section id="thread.concepts.ScopedTryReadWriteLock">
				<title>ScopedTryReadWriteLock Expressions</title>
				
				<para>A ScopedTryReadWriteLock is a refinement of 
				<link linkend="thread.concepts.TryReadWriteLock">TryReadWriteLock</link>.
				For a ScopedTryReadWriteLock type <code>L</code>
				and an object <code>lk</code> of that type,
				and an object <code>m</code> of a type meeting the
				<link linkend="thread.concepts.TryMutex">TryReadWriteMutex</link> requirements,
				and an object <code>s</code> of type <code>read_write_lock_state</code>,
				and an object <code>b</code> of type <code>blocking_mode</code>, 
				the following expressions must be well-formed
				and have the indicated effects.</para>
				
				<table>
					<title>ScopedTryReadWriteLock Expressions</title>
					
					<tgroup cols="2">
						<thead>
							<row>
								<entry>Expression</entry>
								<entry>Effects</entry>
							</row>
						</thead>
						
						<tbody>
							<row>
								<entry><code>L lk(m,s,b);</code></entry>
								<entry>Constructs an object <code>lk</code> and associates read/write mutex
								object <code>m</code> with it, then: if <code>s == read_write_lock_state::read_locked</code>, calls
								<code>read_lock()</code> if <code>b</code>, otherwise <code>try_read_lock()</code>;
								if <code>s==read_write_lock_state::write_locked</code>, calls <code>write_lock()</code> if <code>b</code>,
								otherwise <code>try_write_lock</code>.</entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
			
			<section id="thread.concepts.TimedReadWriteLock">
				<title>TimedReadWriteLock Concept</title>
				
				<para>A TimedReadWriteLock is a refinement of 
				<link linkend="thread.concepts.TryReadWriteLock">TryReadWriteLock</link>. 
				For a TimedReadWriteLock type <code>L</code>
				and an object <code>lk</code> of that type,
				and an object <code>t</code> of type <classname>boost::xtime</classname>, 
				the following expressions must be well-formed
				and have the indicated effects.</para>
				
				<table>
					<title>TimedReadWriteLock Expressions</title>
					
					<tgroup cols="2">
						<thead>
							<row>
								<entry>Expression</entry>
								<entry>Effects</entry>
							</row>
						</thead>
						
						<tbody>
							<row>
								<entry><code>lk.timed_read_lock(t)</code></entry>
								<entry>
									<para>Throws <classname>boost::lock_error</classname>
									if locked().</para>
									
									<para>Makes a blocking attempt to read-lock the associated read/write mutex object,
									and returns <code>true</code> if successful within the specified time <code>t</code>,
									otherwise <code>false</code>. If the associated read/write mutex object is already
									locked by the same thread the behavior is dependent on the <link
									linkend="thread.concepts.locking-strategies">locking
									strategy</link> of the associated read/write mutex object.</para>
								</entry>
							</row>
							<row>
								<entry><code>lk.timed_write_lock(t)</code></entry>
								<entry>
									<para>Throws <classname>boost::lock_error</classname>
									if locked().</para>
									
									<para>Makes a blocking attempt to write-lock the associated read/write mutex object, 
									and returns <code>true</code> if successful within the specified time <code>t</code>,
									otherwise <code>false</code>. If the associated read/write mutex object is already
									locked by the same thread the behavior is dependent on the <link
									linkend="thread.concepts.locking-strategies">locking
									strategy</link> of the associated read/write mutex object.</para>
								</entry>
							</row>
							<row>
								<entry><code>lk.timed_demote(t)</code></entry>
								<entry>
									<para>Throws <classname>boost::lock_error</classname>
									if <code>state() != read_write_lock_state::write_locked</code>.</para> 
									
									<para>Makes a blocking attempt to convert the lock held on the associated
									read/write mutex object from a write-lock to a read-lock without releasing
									the lock, returning <code>true</code> if the attempt is successful
									in the specified time <code>t</code>, otherwise <code>false</code>.</para>
								</entry>
							</row>
							<row>
								<entry><code>lk.timed_promote(t)</code></entry>
								<entry>
									<para>Throws <classname>boost::lock_error</classname>
									if <code>state() != read_write_lock_state::read_locked</code>.</para>
									
									<para>Makes a blocking attempt to convert the lock held on the associated
									read/write mutex object from a read-lock to a write-lock without releasing
									the lock, returning <code>true</code> if the attempt is successful
									in the specified time <code>t</code>, otherwise <code>false</code>.</para>
								</entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
			
			<section id="thread.concepts.ScopedTimedReadWriteLock">
				<title>ScopedTimedReadWriteLock Concept</title>
				
				<para>A ScopedTimedReadWriteLock is a refinement of 
				<link linkend="thread.concepts.TimedReadWriteLock">TimedReadWriteLock</link>. 
				For a ScopedTimedReadWriteLock type <code>L</code>
				and an object <code>lk</code> of that type,
				and an object <code>m</code> of a type meeting the 
				<link linkend="thread.concepts.TimedReadWriteMutex">TimedReadWriteMutex</link> requirements,
				and an object <code>s</code> of type <code>read_write_lock_state</code>,
				and an object <code>t</code> of type <classname>boost::xtime</classname>, 
				and an object <code>b</code> of type <code>blocking_mode</code>, 
				the following expressions must be well-formed and have the
				indicated effects.</para>
				
				<table>
					<title>ScopedTimedReadWriteLock Expressions</title>
					
					<tgroup cols="2">
						<thead>
							<row>
								<entry>Expression</entry>
								<entry>Effects</entry>
							</row>
						</thead>
						
						<tbody>
							<row>
								<entry><code>L lk(m,s,b);</code></entry>
								<entry>Constructs an object <code>lk</code> and associates read/write mutex
								object <code>m</code> with it, then: if <code>s == read_write_lock_state::read_locked</code>, calls
								<code>read_lock()</code> if <code>b</code>, otherwise <code>try_read_lock()</code>;
								if <code>s==read_write_lock_state::write_locked</code>, calls <code>write_lock()</code> if <code>b</code>,
								otherwise <code>try_write_lock</code>.</entry>
							</row>
							<row>
								<entry><code>L lk(m,s,t);</code></entry>
								<entry>Constructs an object <code>lk</code> and associates read/write mutex
								object <code>m</code> with it, then: if <code>s == read_write_lock_state::read_locked</code>, calls
								<code>timed_read_lock(t)</code>; if <code>s==read_write_lock_state::write_locked</code>,
								calls <code>timed_write_lock(t)</code>.</entry>
							</row>
						</tbody>
					</tgroup>
				</table>
			</section>
		</section>

		<section id="thread.concepts.read-write-lock-models">
			<title>Lock Models</title>
			
			<para>&Boost.Thread; currently supplies six models of
			<link linkend="thread.concepts.ReadWriteLock">ReadWriteLock</link>
			and its refinements.</para>
			
			<table>
				<title>Lock Models</title>
				
				<tgroup cols="3">
					<thead>
						<row>
							<entry>Concept</entry>
							<entry>Refines</entry>
							<entry>Models</entry>
						</row>
					</thead>
					
					<tbody>
						<row>
							<entry><link linkend="thread.concepts.ReadWriteLock">ReadWriteLock</link></entry>
							<entry></entry>
							<entry></entry>
						</row>
						<row>
							<entry><link linkend="thread.concepts.ScopedReadWriteLock">ScopedReadWriteLock</link></entry>
							<entry><link linkend="thread.concepts.ReadWriteLock">ReadWriteLock</link></entry>
							<entry>
								<para><classname>boost::read_write_mutex::scoped_read_write_lock</classname></para>
								<para><classname>boost::try_read_write_mutex::scoped_read_write_lock</classname></para>
								<para><classname>boost::timed_read_write_mutex::scoped_read_write_lock</classname></para>
							</entry>
						</row>
						<row>
							<entry><link linkend="thread.concepts.TryReadWriteLock">TryReadWriteLock</link></entry>
							<entry><link linkend="thread.concepts.ReadWriteLock">ReadWriteLock</link></entry>
							<entry></entry>
						</row>
						<row>
							<entry><link linkend="thread.concepts.ScopedTryReadWriteLock">ScopedTryReadWriteLock</link></entry>
							<entry><link linkend="thread.concepts.TryReadWriteLock">TryReadWriteLock</link></entry>
							<entry>
								<para><classname>boost::try_read_write_mutex::scoped_try_read_write_lock</classname></para>
								<para><classname>boost::timed_read_write_mutex::scoped_try_read_write_lock</classname></para>
							</entry>
						</row>
						<row>
							<entry><link linkend="thread.concepts.TimedReadWriteLock">TimedReadWriteLock</link></entry>
							<entry><link linkend="thread.concepts.TryReadWriteLock">TryReadWriteLock</link></entry>
							<entry></entry>
						</row>
						<row>
							<entry><link linkend="thread.concepts.ScopedTimedReadWriteLock">ScopedTimedReadWriteLock</link></entry>
							<entry><link linkend="thread.concepts.TimedReadWriteLock">TimedReadWriteLock</link></entry>
							<entry>
								<para><classname>boost::timed_read_write_mutex::scoped_timed_read_write_lock</classname></para>
							</entry>
						</row>
					</tbody>
				</tgroup>
			</table>
		</section>
	</section>
</section>
