# 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 LevelMutexInfo * | GetPrevious (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]`

Returns true if no class invariant broken, otherwise asserts. This function only gets called in debug builds.

References IsValidList(), and UnlockedLevel.

Referenced by DecrementCount(), IncrementCount(), IsLockedByAnotherThread(), IsLockedByCurrentThread(), IsRecentLock(), Loki::LevelMutex< MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy >::LevelMutex(), LevelMutexInfo(), Loki::LevelMutex< MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy >::Lock(), PostLock(), PreUnlock(), Loki::LevelMutex< MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy >::TryLock(), Loki::LevelMutex< MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy >::Unlock(), Loki::LevelMutex< MutexPolicy, DefaultLevel, ErrorPolicy, WaitPolicy >::~LevelMutex(), and ~LevelMutexInfo().

Here is the call graph for this function:

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:

- LevelMutex.h
- LevelMutex.cpp