Sophie

Sophie

distrib > Fedora > 13 > i386 > by-pkgid > bfea28f33e7373c31a33dc7387b2a0be > files > 94

loki-lib-doc-0.1.7-2.fc12.noarch.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Loki: Loki::LevelMutex&lt; MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy &gt; Class Template Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css">
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.5.8 -->
<div class="navigation" id="top">
  <div class="tabs">
    <ul>
      <li><a href="main.html"><span>Main&nbsp;Page</span></a></li>
      <li><a href="modules.html"><span>Modules</span></a></li>
      <li><a href="namespaces.html"><span>Namespaces</span></a></li>
      <li class="current"><a href="annotated.html"><span>Classes</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
    <li>
      <form action="search.php" method="get">
        <table cellspacing="0" cellpadding="0" border="0">
          <tr>
            <td><label>&nbsp;<u>S</u>earch&nbsp;for&nbsp;</label></td>
            <td><input type="text" name="query" value="" size="20" accesskey="s"/></td>
          </tr>
        </table>
      </form>
    </li>
    </ul>
  </div>
  <div class="tabs">
    <ul>
      <li><a href="annotated.html"><span>Class&nbsp;List</span></a></li>
      <li><a href="classes.html"><span>Class&nbsp;Index</span></a></li>
      <li><a href="hierarchy.html"><span>Class&nbsp;Hierarchy</span></a></li>
      <li><a href="functions.html"><span>Class&nbsp;Members</span></a></li>
    </ul>
  </div>
  <div class="navpath"><a class="el" href="a00192.html">Loki</a>::<a class="el" href="a00070.html">LevelMutex</a>
  </div>
</div>
<div class="contents">
<h1>Loki::LevelMutex&lt; MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy &gt; Class Template Reference</h1><!-- doxytag: class="Loki::LevelMutex" --><!-- doxytag: inherits="Loki::LevelMutexInfo" --><code>#include &lt;LevelMutex.h&gt;</code>
<p>
<div class="dynheader">
Inheritance diagram for Loki::LevelMutex&lt; MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy &gt;:</div>
<div class="dynsection">
<center><font size="2">[<a target="top" href="graph_legend.html">legend</a>]</font></center></div>
<div class="dynheader">
Collaboration diagram for Loki::LevelMutex&lt; MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy &gt;:</div>
<div class="dynsection">
<center><font size="2">[<a target="top" href="graph_legend.html">legend</a>]</font></center></div>

<p>
<a href="a00336.html">List of all members.</a><table border="0" cellpadding="0" cellspacing="0">
<tr><td></td></tr>
<tr><td colspan="2"><br><h2>Public Member Functions</h2></td></tr>
<tr><td class="memItemLeft" nowrap align="right" valign="top">&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="a00070.html#e770e4e5ec2fa120d016eb23b56d988b">LevelMutex</a> (unsigned int level=DefaultLevel)</td></tr>

<tr><td class="memItemLeft" nowrap align="right" valign="top"><a class="anchor" name="b1670bea535a28e439a991fad4056ec2"></a><!-- doxytag: member="Loki::LevelMutex::~LevelMutex" ref="b1670bea535a28e439a991fad4056ec2" args="(void)" -->
&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="a00070.html#b1670bea535a28e439a991fad4056ec2">~LevelMutex</a> (void)</td></tr>

<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">The destructor. <br></td></tr>
<tr><td class="memItemLeft" nowrap align="right" valign="top">const volatile MutexPolicy &amp;&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="a00070.html#9a9abaa6b4148b9b02bd279615872e90">GetMutexPolicy</a> (void) const volatile</td></tr>

<tr><td class="memItemLeft" nowrap align="right" valign="top">virtual MutexErrors::Type&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="a00070.html#042a7938dafd6f149cfd7da46478c0c9">TryLock</a> (void) volatile</td></tr>

<tr><td class="memItemLeft" nowrap align="right" valign="top">virtual MutexErrors::Type&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="a00070.html#95d3742db062548201986f482a9c9b9d">Lock</a> (void) volatile</td></tr>

<tr><td class="memItemLeft" nowrap align="right" valign="top">virtual MutexErrors::Type&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="a00070.html#d4ac0c2a33ff3d98ec0a83f70ce145da">Lock</a> (unsigned int milliSeconds) volatile</td></tr>

<tr><td class="memItemLeft" nowrap align="right" valign="top">virtual MutexErrors::Type&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="a00070.html#553a379257af57ceaef9ed48b0dc8b70">Unlock</a> (void) volatile</td></tr>

</table>
<hr><a name="_details"></a><h2>Detailed Description</h2>
<h3>template&lt;class MutexPolicy, unsigned int DefaultLevel, class ErrorPolicy = ::Loki::ThrowOnBadDesignMutexError, class WaitPolicy = ::Loki::NoMutexWait&gt;<br>
 class Loki::LevelMutex&lt; MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy &gt;</h3>

Levelized mutex class prevents deadlocks by requiring programs to lock mutexes in the same order, and unlock them in reverse order. This is accomplished by forcing each mutex to have a level and forcing code to lock mutexes with higher levels before locking mutexes at lower levels. If you want to lock several mutexes, they must be locked in decreasing order by level, or if they are all of the same level, then locked by <a class="el" href="a00071.html#dde650eae1cad8b4723e68cdb9130283">LevelMutex::MultiLock</a>.<p>
<dl class="user" compact><dt><b>Features</b></dt><dd><ul>
<li>Immune: Very unlikely to deadlock since all mutexes are locked in the same order and unlocked in reverse order.</li><li>Scalable: Can handle any number of mutexes.</li><li>Efficient: Many operations occur in constant time, and most operations require no more than O(m) steps.</li><li>Exception safe: All operations provide strong safety or don't throw.</li><li>Extendable: Can work with existing mutexes through policy-based design.</li><li>Easily Extended: Derived classes only need to implement 5 functions and a mutex to get all the features of this class.</li><li>Re-Entrant: Allows for re-entrancy even if mutexes in policy classes don't.</li><li>Cost-Free: No resource allocations occur in <a class="el" href="a00070.html">LevelMutex</a> - although user-defined policy classes may allocate resources.</li><li>Compact: Each <a class="el" href="a00070.html">LevelMutex</a> object is small.</li><li>Portable: As long as your compiler and libraries can meet the requirements.</li><li>Robust: Maintains data integrity even if exceptions occur in policy classes.</li><li>Affording: Several functions provide information about a mutex which allows client code to easily choose correct actions.</li></ul>
</dd></dl>
<dl class="user" compact><dt><b>Requirements</b></dt><dd><ul>
<li>Your compiler must allow for thread-specific data.</li><li>You must have a threading or mutex library.</li></ul>
</dd></dl>
<dl class="user" compact><dt><b>Policy-Based Design</b></dt><dd>This class hosts 3 policies and a default level. The policy-based design allows users to write their own policies to extend the behaviors of <a class="el" href="a00070.html">LevelMutex</a>. The paragraphs below say how to design a class for each policy.<ul>
<li>MutexPolicy The mutex policy class.</li><li>defaultLevel A level for existing client code that calls a default constructor.</li><li>ErrorPolicy How the mutex should handle error conditions.</li><li>WaitPolicy Whether a thread should wait, and how long in some internal loops.</li></ul>
</dd></dl>
<dl class="user" compact><dt><b>MutexPolicy</b></dt><dd>A policy class that wraps a low-level mutex. <a class="el" href="a00192.html">Loki</a> provides two policy classes for the actual mutex (<a class="el" href="a00133.html">SpinLevelMutex</a> and <a class="el" href="a00126.html">SleepLevelMutex</a>), both of which wrap either pthreads or the Windows CRITICAL_SECTION. If you want to use a mutex mechanism besides one of those, then all you have to do is provide a class which wraps the mutex and implements these functions. explicit SpinLevelMutex( unsigned int level ); virtual ~SpinLevelMutex( void ); virtual MutexErrors::Type <a class="el" href="a00070.html#95d3742db062548201986f482a9c9b9d">Lock( void ) volatile</a>; virtual MutexErrors::Type <a class="el" href="a00070.html#042a7938dafd6f149cfd7da46478c0c9">TryLock( void ) volatile</a>; virtual MutexErrors::Type <a class="el" href="a00070.html#553a379257af57ceaef9ed48b0dc8b70">Unlock( void ) volatile</a>; Indeed, since the base class does most of the work, and provides all the interace and functionality to client classes, a derived class has very few requirements. It only needs to implement a single constructor, the destructor, some virtual functions, and whatever data members it requires. You don't actually need to declare those functions as virtual if the policy class is not a base or child class. In the parlance of design patterns, <a class="el" href="a00070.html">LevelMutex</a> is a Template, and the MutexPolicy is a Strategy.</dd></dl>
<dl class="user" compact><dt><b>DefaultLevel</b></dt><dd>The template class requires a default level to use inside the default constructor. Some existing code calls instantiates mutexes with a default constructor, so the mutex must know what level to use there. Please do not use zero or UnlockedLevel as the default level.</dd></dl>
<dl class="user" compact><dt><b>ErrorPolicy</b></dt><dd>This policy specifies how to handle error conditions. The mutexes can return errors, assert, or throw exceptions. I recommend that debug code use asserts, release code use exceptions, and unit-testing code just return errors. The error policy class only needs to implement one function: static MutexErrors::Type CheckError( MutexErrors::Type error, unsigned int level );</dd></dl>
<dl class="user" compact><dt><b>WaitPolicy</b></dt><dd>This states whether the mutex should wait within some tight internal loops, how the waiting is done, and for how long. A wait policy class could sleep, do nothing, check if other objects need attention, or check if the program received events or notices from the operating system. It only needs to implement one function: static void Wait( void );</dd></dl>
<dl class="user" compact><dt><b>Per-Function Usage</b></dt><dd>If you implement a function with a static local mutex, then you have to insure the function is not called from a lower level via call-backs, virtual functions in interface classes. If the function does get called from a lower level, you are setting up a potential deadlock. <a class="el" href="a00070.html">LevelMutex</a> will detect that by checking the current level and the local mutex's level, so it will refuse to lock the local mutex.</dd></dl>
<dl class="user" compact><dt><b>Per-Object Usage</b></dt><dd>If you use a mutex as a data member of an object to protect that object, then I recommend specifying which functions are volatile and which are not, and then only use the mutex within the volatile functions. You may also want to provide accessor functions so that client code can lock and unlock the mutex either to allow for calling multiple operations without having to lock and unlock before and after each operation, or so they can lock it along with several other objects at the same level.</dd></dl>
<dl class="user" compact><dt><b>Per-Class Usage</b></dt><dd>If you make a static data member within a class, you can use that to lock any resources shared by those objects, or to require threads to act on only one object at a time. You may also want to provide static accessor functions so that client code can lock several other resources at the same level. </dd></dl>
<hr><h2>Constructor &amp; Destructor Documentation</h2>
<a class="anchor" name="e770e4e5ec2fa120d016eb23b56d988b"></a><!-- doxytag: member="Loki::LevelMutex::LevelMutex" ref="e770e4e5ec2fa120d016eb23b56d988b" args="(unsigned int level=DefaultLevel)" -->
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class MutexPolicy , unsigned int DefaultLevel, class ErrorPolicy  = ::Loki::ThrowOnBadDesignMutexError, class WaitPolicy  = ::Loki::NoMutexWait&gt; </div>
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="a00070.html">Loki::LevelMutex</a>&lt; MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy &gt;::<a class="el" href="a00070.html">LevelMutex</a>           </td>
          <td>(</td>
          <td class="paramtype">unsigned int&nbsp;</td>
          <td class="paramname"> <em>level</em> = <code>DefaultLevel</code>          </td>
          <td>&nbsp;)&nbsp;</td>
          <td><code> [inline, explicit]</code></td>
        </tr>
      </table>
</div>
<div class="memdoc">

<p>
This constructor allows callers to replace the default level with another value. It also acts as the default constructor for existing code which uses default construction for mutexes. This is the only time the DefaultLevel template parameter gets used. 
<p>References <a class="el" href="a00242.html#l00545">Loki::LevelMutexInfo::IsValid()</a>.</p>

<p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dynsection">
</div>

</div>
</div><p>
<hr><h2>Member Function Documentation</h2>
<a class="anchor" name="9a9abaa6b4148b9b02bd279615872e90"></a><!-- doxytag: member="Loki::LevelMutex::GetMutexPolicy" ref="9a9abaa6b4148b9b02bd279615872e90" args="(void) const volatile" -->
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class MutexPolicy , unsigned int DefaultLevel, class ErrorPolicy  = ::Loki::ThrowOnBadDesignMutexError, class WaitPolicy  = ::Loki::NoMutexWait&gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">const volatile MutexPolicy&amp; <a class="el" href="a00070.html">Loki::LevelMutex</a>&lt; MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy &gt;::GetMutexPolicy           </td>
          <td>(</td>
          <td class="paramtype">void&nbsp;</td>
          <td class="paramname">          </td>
          <td>&nbsp;)&nbsp;</td>
          <td> const volatile<code> [inline]</code></td>
        </tr>
      </table>
</div>
<div class="memdoc">

<p>
These functions allow callers to access the mutex in case they need to modify specific values in the MutexPolicy (e.g. - sleep time, functors to call as tasks, etc...) There is one function for every combination of const and volatile qualifiers so callers get a reference to a MutexPolicy with the proper qualifiers. 
</div>
</div><p>
<a class="anchor" name="d4ac0c2a33ff3d98ec0a83f70ce145da"></a><!-- doxytag: member="Loki::LevelMutex::Lock" ref="d4ac0c2a33ff3d98ec0a83f70ce145da" args="(unsigned int milliSeconds) volatile" -->
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class MutexPolicy , unsigned int DefaultLevel, class ErrorPolicy  = ::Loki::ThrowOnBadDesignMutexError, class WaitPolicy  = ::Loki::NoMutexWait&gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">virtual MutexErrors::Type <a class="el" href="a00070.html">Loki::LevelMutex</a>&lt; MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy &gt;::Lock           </td>
          <td>(</td>
          <td class="paramtype">unsigned int&nbsp;</td>
          <td class="paramname"> <em>milliSeconds</em>          </td>
          <td>&nbsp;)&nbsp;</td>
          <td> volatile<code> [inline, virtual]</code></td>
        </tr>
      </table>
</div>
<div class="memdoc">

<p>
Attempts to lock mutex, but only waits for a limited amount of time before it gives up. Will return quickly if an error occurs before any attempt to lock. This may throw an exception if the lock failed or an error occurred - if that is what the error policy specifies. <dl compact><dt><b>Parameters:</b></dt><dd>
  <table border="0" cellspacing="2" cellpadding="0">
    <tr><td valign="top"></td><td valign="top"><em>milliSeconds</em>&nbsp;</td><td>How long to wait. </td></tr>
  </table>
</dl>
<dl class="return" compact><dt><b>Returns:</b></dt><dd>An error condition if any occurred, else Success. </dd></dl>

<p>Implements <a class="el" href="a00071.html#5782b9fd9734d95a38ff86ef9532c89b">Loki::LevelMutexInfo</a>.</p>

<p>References <a class="el" href="a00243.html#l00208">Loki::LevelMutexInfo::GetLevel()</a>, <a class="el" href="a00242.html#l00575">Loki::LevelMutexInfo::IsLockedByCurrentThread()</a>, <a class="el" href="a00242.html#l00545">Loki::LevelMutexInfo::IsValid()</a>, and <a class="el" href="a00242.html#l00653">Loki::LevelMutexInfo::PostLock()</a>.</p>

<p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dynsection">
</div>

</div>
</div><p>
<a class="anchor" name="95d3742db062548201986f482a9c9b9d"></a><!-- doxytag: member="Loki::LevelMutex::Lock" ref="95d3742db062548201986f482a9c9b9d" args="(void) volatile" -->
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class MutexPolicy , unsigned int DefaultLevel, class ErrorPolicy  = ::Loki::ThrowOnBadDesignMutexError, class WaitPolicy  = ::Loki::NoMutexWait&gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">virtual MutexErrors::Type <a class="el" href="a00070.html">Loki::LevelMutex</a>&lt; MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy &gt;::Lock           </td>
          <td>(</td>
          <td class="paramtype">void&nbsp;</td>
          <td class="paramname">          </td>
          <td>&nbsp;)&nbsp;</td>
          <td> volatile<code> [inline, virtual]</code></td>
        </tr>
      </table>
</div>
<div class="memdoc">

<p>
Blocking call will attempt to lock mutex and wait until it can lock. This may throw an exception if the lock failed or an error occurred - if that is what the error policy specifies. <dl class="return" compact><dt><b>Returns:</b></dt><dd>An error condition if any occurred, else Success. </dd></dl>

<p>Implements <a class="el" href="a00071.html#c0e21e08ee9974533a4da5008452bd04">Loki::LevelMutexInfo</a>.</p>

<p>References <a class="el" href="a00243.html#l00208">Loki::LevelMutexInfo::GetLevel()</a>, <a class="el" href="a00242.html#l00575">Loki::LevelMutexInfo::IsLockedByCurrentThread()</a>, <a class="el" href="a00242.html#l00545">Loki::LevelMutexInfo::IsValid()</a>, and <a class="el" href="a00242.html#l00653">Loki::LevelMutexInfo::PostLock()</a>.</p>

<p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dynsection">
</div>

</div>
</div><p>
<a class="anchor" name="042a7938dafd6f149cfd7da46478c0c9"></a><!-- doxytag: member="Loki::LevelMutex::TryLock" ref="042a7938dafd6f149cfd7da46478c0c9" args="(void) volatile" -->
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class MutexPolicy , unsigned int DefaultLevel, class ErrorPolicy  = ::Loki::ThrowOnBadDesignMutexError, class WaitPolicy  = ::Loki::NoMutexWait&gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">virtual MutexErrors::Type <a class="el" href="a00070.html">Loki::LevelMutex</a>&lt; MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy &gt;::TryLock           </td>
          <td>(</td>
          <td class="paramtype">void&nbsp;</td>
          <td class="paramname">          </td>
          <td>&nbsp;)&nbsp;</td>
          <td> volatile<code> [inline, virtual]</code></td>
        </tr>
      </table>
</div>
<div class="memdoc">

<p>
Tries to lock mutex, and returns immediately if mutex already locked by another thread. It will return immediately with a value of AlreadyLocked if the mutex was locked by a different thread. It may throw an exception or assert when errors occur if the ErrorPolicy class implements that behavior. <dl class="return" compact><dt><b>Returns:</b></dt><dd>An error condition if any occurred, else Success. </dd></dl>

<p>Implements <a class="el" href="a00071.html#32f89bf087b932de0cdd1151116779b4">Loki::LevelMutexInfo</a>.</p>

<p>References <a class="el" href="a00243.html#l00208">Loki::LevelMutexInfo::GetLevel()</a>, <a class="el" href="a00243.html#l00214">Loki::LevelMutexInfo::GetLockCount()</a>, <a class="el" href="a00242.html#l00545">Loki::LevelMutexInfo::IsValid()</a>, and <a class="el" href="a00242.html#l00653">Loki::LevelMutexInfo::PostLock()</a>.</p>

<p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dynsection">
</div>

</div>
</div><p>
<a class="anchor" name="553a379257af57ceaef9ed48b0dc8b70"></a><!-- doxytag: member="Loki::LevelMutex::Unlock" ref="553a379257af57ceaef9ed48b0dc8b70" args="(void) volatile" -->
<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;class MutexPolicy , unsigned int DefaultLevel, class ErrorPolicy  = ::Loki::ThrowOnBadDesignMutexError, class WaitPolicy  = ::Loki::NoMutexWait&gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">virtual MutexErrors::Type <a class="el" href="a00070.html">Loki::LevelMutex</a>&lt; MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy &gt;::Unlock           </td>
          <td>(</td>
          <td class="paramtype">void&nbsp;</td>
          <td class="paramname">          </td>
          <td>&nbsp;)&nbsp;</td>
          <td> volatile<code> [inline, virtual]</code></td>
        </tr>
      </table>
</div>
<div class="memdoc">

<p>
Unlocks the mutex, or returns an error condition. This may throw an exception if the lock failed or an error occurred - if that is what the error policy specifies. <dl class="return" compact><dt><b>Returns:</b></dt><dd>An error condition if any occurred, else Success. </dd></dl>

<p>Implements <a class="el" href="a00071.html#01c9af5cb0f6870585b864b4557e9242">Loki::LevelMutexInfo</a>.</p>

<p>References <a class="el" href="a00243.html#l00208">Loki::LevelMutexInfo::GetLevel()</a>, <a class="el" href="a00242.html#l00545">Loki::LevelMutexInfo::IsValid()</a>, <a class="el" href="a00242.html#l00653">Loki::LevelMutexInfo::PostLock()</a>, and <a class="el" href="a00242.html#l00669">Loki::LevelMutexInfo::PreUnlock()</a>.</p>

<p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dynsection">
</div>

</div>
</div><p>
<hr>The documentation for this class was generated from the following file:<ul>
<li><a class="el" href="a00158.html">LevelMutex.h</a></ul>
</div>
<hr size="1"><address style="text-align: right;"><small>Generated on Thu Jan 29 18:51:43 2009 for Loki by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.8 </small></address>
</body>
</html>