Loki::LevelMutexInfo Class Reference

#include <LevelMutex.h>

Inheritance diagram for Loki::LevelMutexInfo:
[legend]
Collaboration diagram for Loki::LevelMutexInfo:
[legend]

List of all members.

Classes

class  Checker
class  MutexUndoer

Public Types

typedef ::std::vector
< volatile LevelMutexInfo * > 
MutexContainer
 Container for locking multiple mutexes at once.

Public Member Functions

unsigned int GetLevel (void) const volatile
 Returns the level of this mutex.
bool IsLocked (void) const volatile
 Returns true if this mutex was locked at least once.
unsigned int GetLockCount (void) const volatile
 Returns count of how many times this mutex got locked.
const volatile LevelMutexInfoGetPrevious (void) const volatile
 Returns pointer to mutex previously locked by the thread which locked this.
virtual MutexErrors::Type TryLock (void) volatile=0
virtual MutexErrors::Type Lock (void) volatile=0
virtual MutexErrors::Type Lock (unsigned int milliSeconds) volatile=0
virtual MutexErrors::Type Unlock (void) volatile=0
bool IsRecentLock (void) const volatile
bool IsRecentLock (unsigned int count) const volatile
bool IsLockedByCurrentThread (void) const volatile
 Returns true if this was locked by current thread.
bool IsLockedByAnotherThread (void) const volatile
 Returns true if this was locked by another thread.

Static Public Member Functions

static MutexErrors::Type MultiLock (MutexContainer &mutexes)
static MutexErrors::Type MultiLock (MutexContainer &mutexes, unsigned int milliSeconds)
static MutexErrors::Type MultiUnlock (MutexContainer &mutexes)
static const volatile
LevelMutexInfo
GetCurrentMutex (void)

Static Public Attributes

static const unsigned int UnlockedLevel = 0xFFFFFFFF

Protected Member Functions

 LevelMutexInfo (unsigned int level)
virtual ~LevelMutexInfo (void)
 The destructor only gets called by the derived class.
void PostLock (void) volatile
void PreUnlock (void) volatile
 Gets called just before an attempt to unlock a mutex.
void IncrementCount (void) volatile
 Called to relock a mutex already locked by the current thread.
void DecrementCount (void) volatile
 Called to unlock a mutex locked multiple times by the current thread.
bool IsValid (void) const volatile

Static Protected Member Functions

static bool IsValidList (void)


Detailed Description

This monolithic base class stores common info for a template class used to control mutexes. The template class, LevelMutex, is policy-based class.

Implementation
Each thread has a list of mutexes it locked. When a mutex first gets locked, it gets added to the head of the list. If locked again, LevelMutex merely increments a count. When unlocked, the count gets decremented until it reaches zero, and then it gets removed from the list. Each mutex has a pointer to the mutex most recently locked by the current thread. The current level of a thread is always the level of the most recently locked mutex, or UnlockedLevel if the thread does not have any mutexes locked now. A mutex is considered "recently" locked if it is at the head of the list, or the same level as the current mutex and also locked by the current thread.
Class Invariants
This class maintains invariants for each LevelMutexInfo so that no function calls corrupt a mutex. Each function makes a call to IsValid at the start so that LevelMutex knows it acts on valid internal data. Many functions call IsValid again when they return to insure the function did not leave any data in an invalid state. The exit call to IsValid occurs through a tiny helper class called Checker to insure all data remain valid even when exceptions occur. Another helper class, MutexUndoer, unlocks mutexes in a container if an exception occurs during calls to MultiLock.
Error Results
Many functions return an enum value to indicate an error status. Many enum values indicate errors detected within LevelMutex, but some indicate errors found in policy classes, SpinLevelMutex and SleepLevelMutex.

Constructor & Destructor Documentation

Loki::LevelMutexInfo::LevelMutexInfo ( unsigned int  level  )  [explicit, protected]

This is the only available constructor, and it forces any derived class to set a level for each mutex.

References IsValid().

Here is the call graph for this function:


Member Function Documentation

const volatile LevelMutexInfo * Loki::LevelMutexInfo::GetCurrentMutex ( void   )  [static]

Gives pointer to most recently locked mutex, or NULL if nothing locked. The pointer is for a const mutex so the mutex can't be modified inappropriately. The pointer is for a volatile mutex so callers can call volatile member functions to get info about the mutex.

References IsValidList().

Referenced by Loki::CountLocksInCurrentThread(), Loki::CountMutexesAtCurrentLevel(), Loki::CountMutexesInCurrentThread(), and Loki::GetCurrentThreadsLevel().

Here is the call graph for this function:

bool Loki::LevelMutexInfo::IsRecentLock ( unsigned int  count  )  const volatile

Returns true if this mutex was locked within the last count mutexes.

Parameters:
count How many recent mutexes to look through to find this mutex.

References IsValid(), and m_previous.

Here is the call graph for this function:

bool Loki::LevelMutexInfo::IsRecentLock ( void   )  const volatile

Returns true if this mutex was locked by current thread, and level is the same as the current thread's level. Which means this was the most recently locked mutex, or it was locked along with several others of the same level recently.

References IsValid(), m_level, and m_previous.

Referenced by Loki::DoMutexesMatchContainer().

Here is the call graph for this function:

bool Loki::LevelMutexInfo::IsValid ( void   )  const volatile [protected]

bool Loki::LevelMutexInfo::IsValidList ( void   )  [static, protected]

Returns true if linked-list of locked mutexes in this thread is valid. Which means the list has no loops, and each previous mutex on the list has a higher or same level as the current mutex. Called by IsValid.

References m_level, and m_previous.

Referenced by GetCurrentMutex(), IsValid(), MultiLock(), and MultiUnlock().

virtual MutexErrors::Type Loki::LevelMutexInfo::Lock ( unsigned int  milliSeconds  )  volatile [pure virtual]

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.

Parameters:
milliSeconds How long to wait.
Returns:
An error condition if any occurred, else Success.

Implemented in Loki::LevelMutex< MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy >.

virtual MutexErrors::Type Loki::LevelMutexInfo::Lock ( void   )  volatile [pure virtual]

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.

Returns:
An error condition if any occurred, else Success.

Implemented in Loki::LevelMutex< MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy >.

Referenced by Loki::MutexLocker::Lock(), and Loki::MutexLocker::MutexLocker().

MutexErrors::Type Loki::LevelMutexInfo::MultiLock ( MutexContainer mutexes,
unsigned int  milliSeconds 
) [static]

Locks several mutexes at once. Requires O(m + n*n + n*t) actions where m is the number of mutexes currently locked by the thread, n is the number of mutexes in the container, and t is the wait time for each mutex. This provides strong exception safety. If an exception occurs, any mutexes that were locked during this call will ge unlocked.

Parameters:
mutexes Container of pointers to mutexes. Container must have at least 1 mutex, all mutexes must have the same level, no NULL pointers, and all mutexes must not exceed the thread's current level. This sorts the container by address order.
milliSeconds Amount of time to wait for each mutex.
Returns:
Enum value indicating success or error.

References Loki::LevelMutexInfo::LevelMutexInfo::MutexUndoer::Cancel(), DoErrorCheck(), Loki::DoMutexesMatchContainer(), Loki::GetCurrentThreadsLevel(), IsValidList(), MultiLock(), Loki::LevelMutexInfo::LevelMutexInfo::MutexUndoer::SetPlace(), and UnlockedLevel.

Here is the call graph for this function:

MutexErrors::Type Loki::LevelMutexInfo::MultiLock ( MutexContainer mutexes  )  [static]

Locks several mutexes at once. Requires O(m + n*n) actions where m is the number of mutexes currently locked by the thread and n is the number of mutexes in the container. This provides strong exception safety. If an exception occurs, any mutexes that were locked during this call will get unlocked.

Parameters:
mutexes Container of pointers to mutexes. Container must have at least 1 mutex, all mutexes must have the same level, no NULL pointers, and all mutexes must not exceed the thread's current level. This sorts the container by address order.
Returns:
Enum value indicating success or error.

References Loki::LevelMutexInfo::LevelMutexInfo::MutexUndoer::Cancel(), DoErrorCheck(), Loki::DoMutexesMatchContainer(), Loki::GetCurrentThreadsLevel(), IsValidList(), Loki::LevelMutexInfo::LevelMutexInfo::MutexUndoer::SetPlace(), and UnlockedLevel.

Referenced by Loki::MultiMutexLocker::Lock(), MultiLock(), and Loki::MultiMutexLocker::MultiMutexLocker().

Here is the call graph for this function:

MutexErrors::Type Loki::LevelMutexInfo::MultiUnlock ( MutexContainer mutexes  )  [static]

Unlocks several mutexes at once. Requires O(m) actions where m is the number of mutexes in the container. This provides strong exception safety. If an exception occurs when unlocking one mutex, other mutexes in the container get unlocked anyway.

Parameters:
mutexes Container of pointers to mutexes. Container must have at least 1 mutex, all mutexes must have the same level, no NULL pointers, and all mutexes must be locked by the current thread. This sorts the container dby address order.
Returns:
Enum value indicating success or error.

References DoErrorCheck(), Loki::DoMutexesMatchContainer(), IsValidList(), UnlockedLevel, and UnlockThis().

Referenced by Loki::MultiMutexLocker::Unlock(), and Loki::MultiMutexLocker::~MultiMutexLocker().

Here is the call graph for this function:

void Loki::LevelMutexInfo::PostLock ( void   )  volatile [protected]

This gets called after each call to DoLock and DoTryLock to make sure the data members in this object get set correctly.

References IsLockedByCurrentThread(), and IsValid().

Referenced by Loki::LevelMutex< MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy >::Lock(), Loki::LevelMutex< MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy >::TryLock(), and Loki::LevelMutex< MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy >::Unlock().

Here is the call graph for this function:

virtual MutexErrors::Type Loki::LevelMutexInfo::TryLock ( void   )  volatile [pure virtual]

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.

Returns:
An error condition if any occurred, else Success.

Implemented in Loki::LevelMutex< MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy >.

virtual MutexErrors::Type Loki::LevelMutexInfo::Unlock ( void   )  volatile [pure virtual]

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.

Returns:
An error condition if any occurred, else Success.

Implemented in Loki::LevelMutex< MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy >.

Referenced by Loki::MutexLocker::Unlock(), and Loki::MutexLocker::~MutexLocker().


Member Data Documentation

const unsigned int Loki::LevelMutexInfo::UnlockedLevel = 0xFFFFFFFF [static]

Level for thread that has not locked any mutex. Maximum possible level for a mutex is UnlockedLevel-1; No mutex may have a level of UnlockedLevel.

Referenced by Loki::DoMutexesMatchContainer(), Loki::GetCurrentThreadsLevel(), IsValid(), MultiLock(), and MultiUnlock().


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

Generated on Thu Jan 29 18:51:42 2009 for Loki by  doxygen 1.5.8