VRUT::ReadWriteMutex Class Reference

Multiple clients may read simultaneously but write access is exclusive. Recursive locking is possible with limitations. More...

#include <rwlock.h>

Inheritance diagram for VRUT::ReadWriteMutex:

VRUT::SceneNode VRUT::Camera VRUT::GeometryNode VRUT::LightNode

List of all members.

Public Member Functions

 ReadWriteMutex ()
 Class constructor.
bool IsOk () const
 Check if initialized properly.
void ReadLock () const
 Acquire read lock.
void ReadUnlock () const
 Release read lock.
void WriteLock ()
 Acquire write lock.
void WriteUnlock ()
 Release write lock.

Static Public Attributes

static const unsigned MAX_READERS = 32
 Number of maximum simultaneous readers.

Private Types

typedef std::list< LockOwnerLockOwnerList

Private Member Functions

LockOwnerList::iterator getCurrentReader () const
 Get list iterator for current reader if any.

Private Attributes

wxMutex mutex
 Main mutex.
wxMutex semMutex
 Semaphore mutex for exclusive writer access.
wxSemaphore semaphore
 Semaphore for limited access to resource.
LockOwnerList readers
 List of current readers info.
LockOwner writer
 Current writer info.

Classes

struct  LockOwner
 Thread ID and recursive locks data. More...


Detailed Description

Multiple clients may read simultaneously but write access is exclusive. Recursive locking is possible with limitations.

Definition at line 22 of file rwlock.h.


Member Typedef Documentation

typedef std::list<LockOwner> VRUT::ReadWriteMutex::LockOwnerList [private]

Definition at line 44 of file rwlock.h.


Constructor & Destructor Documentation

VRUT::ReadWriteMutex::ReadWriteMutex (  )  [inline]

Class constructor.

Definition at line 29 of file rwlock.h.

00029                                : semaphore(MAX_READERS, MAX_READERS)
00030               {
00031                      writer.recursiveLocks = 0;
00032                      writer.threadID = 0;
00033               }


Member Function Documentation

LockOwnerList::iterator VRUT::ReadWriteMutex::getCurrentReader (  )  const [inline, private]

Get list iterator for current reader if any.

Definition at line 58 of file rwlock.h.

00059               {
00060                      wxThreadIdType threadID = wxThread::GetCurrentId();
00061                      for (LockOwnerList::iterator it = readers.begin(); it != readers.end(); it++)
00062                             if (it->threadID == threadID)
00063                                    return it;
00064                      return readers.end();
00065               }

bool VRUT::ReadWriteMutex::IsOk (  )  const [inline]

Check if initialized properly.

Definition at line 69 of file rwlock.h.

00070               {
00071                      return mutex.IsOk() && semMutex.IsOk();
00072               }

void VRUT::ReadWriteMutex::ReadLock (  )  const [inline]

Acquire read lock.

Do we need to wait or is it our thread that owns it

If our thread hasn't readlocked but has writelocked we don't need to wait

Definition at line 75 of file rwlock.h.

00076               {
00077                      mutex.Lock();
00079                      wxThreadIdType threadID = wxThread::GetCurrentId();
00080                      LockOwnerList::iterator ourReader = getCurrentReader();
00081                      if (ourReader != readers.end())
00082                             ourReader->recursiveLocks++;
00083                      else
00084                      {
00085                             LockOwner lo = { threadID, 1 };
00086                             readers.push_back(lo);
00088                             if (writer.recursiveLocks == 0 || writer.threadID != threadID)
00089                             {
00090                                    mutex.Unlock();
00091                                    semaphore.Wait();
00092                                    return;
00093                             }
00094                      }
00095                      mutex.Unlock();
00096               }

void VRUT::ReadWriteMutex::ReadUnlock (  )  const [inline]

Release read lock.

Definition at line 99 of file rwlock.h.

00100               {
00101                      wxMutexLocker lock(mutex);
00102                      LockOwnerList::iterator ourReader = getCurrentReader();
00103                      if (ourReader != readers.end())
00104                      {
00105                             if (--ourReader->recursiveLocks == 0)
00106                             {
00107                                    readers.erase(ourReader);
00108                                    semaphore.Post();
00109                             }
00110                      }
00111                      else
00112                             LOGERROR(wxT("<ReadWriteMutex>Read unlock called with no matching previous read lock"));
00113               }

void VRUT::ReadWriteMutex::WriteLock (  )  [inline]

Acquire write lock.

Do we need to wait or is it our thread that owns it

Definition at line 116 of file rwlock.h.

00117               {
00118                      mutex.Lock();
00119                      
00121                      wxThreadIdType threadID = wxThread::GetCurrentId();
00122                      if (writer.recursiveLocks && writer.threadID == threadID)
00123                             writer.recursiveLocks++;
00124                      else
00125                      {
00126                             mutex.Unlock();
00127                             wxMutexLocker semLock(semMutex);
00128                             for (unsigned i = 0; i < MAX_READERS; i++)
00129                                    semaphore.Wait();
00130                             mutex.Lock();
00131                             wxASSERT_MSG(writer.threadID == 0, wxT("<ReadWriteMutex>Write lock was not unlocked properly"));
00132                             writer.threadID = threadID;
00133                             writer.recursiveLocks = 1;
00134                      }
00135                      mutex.Unlock();
00136               }

void VRUT::ReadWriteMutex::WriteUnlock (  )  [inline]

Release write lock.

Definition at line 139 of file rwlock.h.

00140               {
00141                      wxMutexLocker lock(mutex);
00142                      wxThreadIdType threadID = wxThread::GetCurrentId();
00143                      wxASSERT_MSG(writer.threadID == threadID, wxT("<ReadWriteMutex>Unlocking write lock locked by different thread"));
00144                      if (--writer.recursiveLocks == 0)
00145                      {
00146                             for (unsigned i = 0; i < MAX_READERS; i++)
00147                                    semaphore.Post();
00148                             writer.threadID = 0;
00149                      }
00150               }


Member Data Documentation

const unsigned VRUT::ReadWriteMutex::MAX_READERS = 32 [static]

Number of maximum simultaneous readers.

Definition at line 26 of file rwlock.h.

wxMutex VRUT::ReadWriteMutex::mutex [mutable, private]

Main mutex.

Definition at line 47 of file rwlock.h.

wxMutex VRUT::ReadWriteMutex::semMutex [private]

Semaphore mutex for exclusive writer access.

Definition at line 49 of file rwlock.h.

wxSemaphore VRUT::ReadWriteMutex::semaphore [mutable, private]

Semaphore for limited access to resource.

Definition at line 51 of file rwlock.h.

List of current readers info.

Definition at line 53 of file rwlock.h.

Current writer info.

Definition at line 55 of file rwlock.h.


The documentation for this class was generated from the following file:

Generated on Tue Mar 10 14:41:44 2009 for VRUT by  doxygen 1.5.5