csutil/threading/rwmutex.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

csutil/threading/rwmutex.h

    00001 /*
    00002  (C) Copyright 2006-8 Anthony Williams
    00003
    00004   Distributed under the Boost Software License, Version 1.0. (See
    00005   accompanying file LICENSE_1_0.txt or copy at
    00006   http://www.boost.org/LICENSE_1_0.txt)
    00007 */
    00008
    00009 #ifndef __CS_CSUTIL_THREADING_RWMUTEX_H__
    00010 #define __CS_CSUTIL_THREADING_RWMUTEX_H__
    00011
    00012 #include "csutil/threading/condition.h"
    00013 #include "csutil/threading/mutex.h"
    00014
    00015 namespace CS
    00016 {
    00017 namespace Threading
    00018 {
    00022   class ReadWriteMutex
    00023   {
    00024   private:
    00025     struct StateData
    00026     {
    00027       unsigned shared_count;
    00028       bool exclusive;
    00029       bool upgrade;
    00030       bool exclusive_waiting_blocked;
    00031
    00032       StateData() : shared_count(0),
    00033         exclusive(false), upgrade(false),
    00034         exclusive_waiting_blocked(false)
    00035       {
    00036       }
    00037     };
    00038
    00039     StateData state;
    00040     Mutex stateChange;
    00041     Condition sharedCond;
    00042     Condition exclusiveCond;
    00043     Condition upgradeCond;
    00044
    00045     void ReleaseWaiters()
    00046     {
    00047       exclusiveCond.NotifyOne();
    00048       sharedCond.NotifyAll();
    00049     }
    00050
    00051   public:
    00052     ReadWriteMutex()
    00053     {
    00054     }
    00055
    00056     ~ReadWriteMutex()
    00057     {
    00058     }
    00059
    00060     void ReadLock()
    00061     {
    00062       MutexScopedLock lock(stateChange);
    00063
    00064       while(state.exclusive || state.exclusive_waiting_blocked)
    00065       {
    00066         sharedCond.Wait(stateChange);
    00067       }
    00068       ++state.shared_count;
    00069     }
    00070
    00071     void ReadUnlock()
    00072     {
    00073       MutexScopedLock lock(stateChange);
    00074       bool const last_reader=!--state.shared_count;
    00075
    00076       if(last_reader)
    00077       {
    00078         if(state.upgrade)
    00079         {
    00080           state.upgrade=false;
    00081           state.exclusive=true;
    00082           upgradeCond.NotifyOne();
    00083         }
    00084         else
    00085         {
    00086           state.exclusive_waiting_blocked=false;
    00087         }
    00088         ReleaseWaiters();
    00089       }
    00090     }
    00091
    00092     void WriteLock()
    00093     {
    00094       MutexScopedLock lock(stateChange);
    00095
    00096       while(state.shared_count || state.exclusive)
    00097       {
    00098         state.exclusive_waiting_blocked=true;
    00099         exclusiveCond.Wait(stateChange);
    00100       }
    00101       state.exclusive=true;
    00102     }
    00103
    00104     void WriteUnlock()
    00105     {
    00106       MutexScopedLock lock(stateChange);
    00107       state.exclusive=false;
    00108       state.exclusive_waiting_blocked=false;
    00109       ReleaseWaiters();
    00110     }
    00111
    00112     void UpgradeLock()
    00113     {
    00114       MutexScopedLock lock(stateChange);
    00115       while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
    00116       {
    00117         sharedCond.Wait(stateChange);
    00118       }
    00119       ++state.shared_count;
    00120       state.upgrade=true;
    00121     }
    00122
    00123     void UpgradeUnlock()
    00124     {
    00125       MutexScopedLock lock(stateChange);
    00126       state.upgrade=false;
    00127       bool const last_reader=!--state.shared_count;
    00128
    00129       if(last_reader)
    00130       {
    00131         state.exclusive_waiting_blocked=false;
    00132         ReleaseWaiters();
    00133       }
    00134     }
    00135
    00136     void UpgradeUnlockAndWriteLock()
    00137     {
    00138       MutexScopedLock lock(stateChange);
    00139       --state.shared_count;
    00140       while(state.shared_count)
    00141       {
    00142         upgradeCond.Wait(stateChange);
    00143       }
    00144       state.upgrade=false;
    00145       state.exclusive=true;
    00146     }
    00147
    00148     void WriteUnlockAndUpgradeLock()
    00149     {
    00150       MutexScopedLock lock(stateChange);
    00151       state.exclusive=false;
    00152       state.upgrade=true;
    00153       ++state.shared_count;
    00154       state.exclusive_waiting_blocked=false;
    00155       ReleaseWaiters();
    00156     }
    00157
    00158     void WriteUnlockAndReadLock()
    00159     {
    00160       MutexScopedLock lock(stateChange);
    00161       state.exclusive=false;
    00162       ++state.shared_count;
    00163       state.exclusive_waiting_blocked=false;
    00164       ReleaseWaiters();
    00165     }
    00166
    00167     void UpgradeUnlockAndReadLock()
    00168     {
    00169       MutexScopedLock lock(stateChange);
    00170       state.upgrade=false;
    00171       state.exclusive_waiting_blocked=false;
    00172       ReleaseWaiters();
    00173     }
    00174   };
    00175
    00176   class ScopedWriteLock
    00177   {
    00178   public:
    00179     ScopedWriteLock (ReadWriteMutex& lockObj)
    00180       : lockObj (lockObj)
    00181     {
    00182       lockObj.WriteLock ();
    00183     }
    00184
    00185     ~ScopedWriteLock ()
    00186     {
    00187       lockObj.WriteUnlock ();
    00188     }
    00189
    00190   private:
    00191     ReadWriteMutex& lockObj;
    00192   };
    00193
    00194   class ScopedReadLock
    00195   {
    00196   public:
    00197     ScopedReadLock (ReadWriteMutex& lockObj)
    00198       : lockObj (lockObj)
    00199     {
    00200       lockObj.ReadLock ();
    00201     }
    00202
    00203     ~ScopedReadLock ()
    00204     {
    00205       lockObj.ReadUnlock ();
    00206     }
    00207
    00208   private:
    00209     ReadWriteMutex& lockObj;
    00210   };
    00211
    00212   class ScopedUpgradeableLock
    00213   {
    00214   public:
    00215     ScopedUpgradeableLock (ReadWriteMutex& lockObj)
    00216       : lockObj (lockObj)
    00217     {
    00218       lockObj.UpgradeLock ();
    00219     }
    00220
    00221     ~ScopedUpgradeableLock ()
    00222     {
    00223       lockObj.UpgradeUnlock ();
    00224     }
    00225
    00226   private:
    00227     ReadWriteMutex& lockObj;
    00228   };
    00229 }
    00230 }
    00231
    00232 #endif