Overloaded functions for volatile to make better use of Memento and Loki::Checker.
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@1180 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
42786afc4b
commit
f306c39e6e
2 changed files with 60 additions and 26 deletions
|
@ -272,11 +272,15 @@ protected:
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit Memento( const volatile LevelMutexInfo & mutex );
|
explicit Memento( const LevelMutexInfo & mutex );
|
||||||
|
|
||||||
bool operator == ( const volatile LevelMutexInfo & mutex ) const;
|
bool operator == ( const LevelMutexInfo & mutex ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/// Copy-assignment operator is not implemented.
|
||||||
|
Memento & operator = ( const Memento & );
|
||||||
|
|
||||||
/// Level of this mutex.
|
/// Level of this mutex.
|
||||||
const unsigned int m_level;
|
const unsigned int m_level;
|
||||||
|
|
||||||
|
@ -295,7 +299,7 @@ protected:
|
||||||
exception. The checkers only get used in debug builds, and get optimized away in
|
exception. The checkers only get used in debug builds, and get optimized away in
|
||||||
release builds.
|
release builds.
|
||||||
*/
|
*/
|
||||||
typedef ::Loki::CheckFor< volatile LevelMutexInfo, Memento > CheckFor;
|
typedef ::Loki::CheckFor< const LevelMutexInfo, Memento > CheckFor;
|
||||||
|
|
||||||
/** @class MutexUndoer
|
/** @class MutexUndoer
|
||||||
Undoes actions by MultiLock if an exception occurs. It keeps track of
|
Undoes actions by MultiLock if an exception occurs. It keeps track of
|
||||||
|
@ -362,13 +366,13 @@ protected:
|
||||||
/** Returns true if no class invariant broken, otherwise asserts. This function
|
/** Returns true if no class invariant broken, otherwise asserts. This function
|
||||||
only gets called in debug builds.
|
only gets called in debug builds.
|
||||||
*/
|
*/
|
||||||
bool IsValid( void ) const;
|
bool IsValid2( void ) const;
|
||||||
|
|
||||||
/// Returns true if all pre-conditions for PostLock function are valid.
|
/// Returns true if all pre-conditions for PostLock function are valid.
|
||||||
bool PostLockValidator( void ) const volatile;
|
bool PostLockValidator( void ) const;
|
||||||
|
|
||||||
/// Returns true if all pre-conditions for PreUnlock function are valid.
|
/// Returns true if all pre-conditions for PreUnlock function are valid.
|
||||||
bool PreUnlockValidator( void ) const volatile;
|
bool PreUnlockValidator( void ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -395,16 +399,22 @@ private:
|
||||||
/// Called only by MultiUnlock to unlock each particular mutex within a container.
|
/// Called only by MultiUnlock to unlock each particular mutex within a container.
|
||||||
virtual MutexErrors::Type UnlockThis( void ) volatile = 0;
|
virtual MutexErrors::Type UnlockThis( void ) volatile = 0;
|
||||||
|
|
||||||
|
void PostLock( void );
|
||||||
|
|
||||||
/** The actual implementation of IsLockedByCurrentThread. This does not do any
|
/** The actual implementation of IsLockedByCurrentThread. This does not do any
|
||||||
invariant checking because the functions which call it already have.
|
invariant checking because the functions which call it already have.
|
||||||
*/
|
*/
|
||||||
bool IsLockedByCurrentThreadImpl( void ) const volatile;
|
bool IsLockedByCurrentThreadImpl( void ) const volatile;
|
||||||
|
|
||||||
|
bool IsLockedByCurrentThreadImpl( void ) const;
|
||||||
|
|
||||||
/** Does just the opposite of IsLockedByCurrentThread. Called as a post-condition
|
/** Does just the opposite of IsLockedByCurrentThread. Called as a post-condition
|
||||||
check by another function.
|
check by another function.
|
||||||
*/
|
*/
|
||||||
bool IsNotLockedByCurrentThread( void ) const volatile;
|
bool IsNotLockedByCurrentThread( void ) const volatile;
|
||||||
|
|
||||||
|
bool IsNotLockedByCurrentThread( void ) const;
|
||||||
|
|
||||||
/// Pointer to singly-linked list of mutexes locked by the current thread.
|
/// Pointer to singly-linked list of mutexes locked by the current thread.
|
||||||
static LOKI_THREAD_LOCAL volatile LevelMutexInfo * s_currentMutex;
|
static LOKI_THREAD_LOCAL volatile LevelMutexInfo * s_currentMutex;
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,7 @@ MutexErrors::Type DoMutexesMatchContainer( const LevelMutexInfo::MutexContainer
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
LevelMutexInfo::Memento::Memento( const volatile LevelMutexInfo & mutex ) :
|
LevelMutexInfo::Memento::Memento( const LevelMutexInfo & mutex ) :
|
||||||
m_level( mutex.m_level ),
|
m_level( mutex.m_level ),
|
||||||
m_count( mutex.m_count ),
|
m_count( mutex.m_count ),
|
||||||
m_previous( mutex.m_previous ),
|
m_previous( mutex.m_previous ),
|
||||||
|
@ -243,7 +243,7 @@ LevelMutexInfo::Memento::Memento( const volatile LevelMutexInfo & mutex ) :
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool LevelMutexInfo::Memento::operator == ( const volatile LevelMutexInfo & mutex ) const
|
bool LevelMutexInfo::Memento::operator == ( const LevelMutexInfo & mutex ) const
|
||||||
{
|
{
|
||||||
assert( this != nullptr );
|
assert( this != nullptr );
|
||||||
|
|
||||||
|
@ -593,6 +593,14 @@ LevelMutexInfo::~LevelMutexInfo( void )
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool LevelMutexInfo::IsValid( void ) const volatile
|
bool LevelMutexInfo::IsValid( void ) const volatile
|
||||||
|
{
|
||||||
|
const LevelMutexInfo * pThis = const_cast< const LevelMutexInfo * >( this );
|
||||||
|
return pThis->IsValid2();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool LevelMutexInfo::IsValid2( void ) const
|
||||||
{
|
{
|
||||||
assert( nullptr != this );
|
assert( nullptr != this );
|
||||||
assert( LevelMutexInfo::UnlockedLevel != m_level );
|
assert( LevelMutexInfo::UnlockedLevel != m_level );
|
||||||
|
@ -604,14 +612,6 @@ bool LevelMutexInfo::IsValid( void ) const volatile
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool LevelMutexInfo::IsValid( void ) const
|
|
||||||
{
|
|
||||||
const volatile LevelMutexInfo * pThis = const_cast< const volatile LevelMutexInfo * >( this );
|
|
||||||
return pThis->IsValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void LevelMutexInfo::IncrementCount( void ) volatile
|
void LevelMutexInfo::IncrementCount( void ) volatile
|
||||||
{
|
{
|
||||||
assert( IsValid() );
|
assert( IsValid() );
|
||||||
|
@ -636,7 +636,8 @@ bool LevelMutexInfo::IsLockedByCurrentThread( void ) const volatile
|
||||||
// gets called by various functions that are called to clean up after an exception
|
// gets called by various functions that are called to clean up after an exception
|
||||||
// is thrown
|
// is thrown
|
||||||
LOKI_MUTEX_DEBUG_CODE(
|
LOKI_MUTEX_DEBUG_CODE(
|
||||||
CheckFor::NoChange checker( this, &LevelMutexInfo::IsValid );
|
const LevelMutexInfo * pThis = const_cast< const LevelMutexInfo * >( this );
|
||||||
|
CheckFor::NoChange checker( pThis, &LevelMutexInfo::IsValid2 );
|
||||||
(void)checker;
|
(void)checker;
|
||||||
)
|
)
|
||||||
return IsLockedByCurrentThreadImpl();
|
return IsLockedByCurrentThreadImpl();
|
||||||
|
@ -645,6 +646,14 @@ bool LevelMutexInfo::IsLockedByCurrentThread( void ) const volatile
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool LevelMutexInfo::IsLockedByCurrentThreadImpl( void ) const volatile
|
bool LevelMutexInfo::IsLockedByCurrentThreadImpl( void ) const volatile
|
||||||
|
{
|
||||||
|
const LevelMutexInfo * pThis = const_cast< const LevelMutexInfo * >( this );
|
||||||
|
return pThis->IsLockedByCurrentThreadImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool LevelMutexInfo::IsLockedByCurrentThreadImpl( void ) const
|
||||||
{
|
{
|
||||||
if ( !IsLocked() )
|
if ( !IsLocked() )
|
||||||
return false;
|
return false;
|
||||||
|
@ -681,7 +690,8 @@ bool LevelMutexInfo::IsNotLockedByCurrentThread( void ) const volatile
|
||||||
bool LevelMutexInfo::IsRecentLock( void ) const volatile
|
bool LevelMutexInfo::IsRecentLock( void ) const volatile
|
||||||
{
|
{
|
||||||
LOKI_MUTEX_DEBUG_CODE(
|
LOKI_MUTEX_DEBUG_CODE(
|
||||||
CheckFor::NoThrowOrChange checker( this, &LevelMutexInfo::IsValid );
|
const LevelMutexInfo * pThis = const_cast< const LevelMutexInfo * >( this );
|
||||||
|
CheckFor::NoThrowOrChange checker( pThis, &LevelMutexInfo::IsValid2 );
|
||||||
(void)checker;
|
(void)checker;
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -705,7 +715,8 @@ bool LevelMutexInfo::IsRecentLock( void ) const volatile
|
||||||
bool LevelMutexInfo::IsRecentLock( std::size_t count ) const volatile
|
bool LevelMutexInfo::IsRecentLock( std::size_t count ) const volatile
|
||||||
{
|
{
|
||||||
LOKI_MUTEX_DEBUG_CODE(
|
LOKI_MUTEX_DEBUG_CODE(
|
||||||
CheckFor::NoThrowOrChange checker( this, &LevelMutexInfo::IsValid );
|
const LevelMutexInfo * pThis = const_cast< const LevelMutexInfo * >( this );
|
||||||
|
CheckFor::NoThrowOrChange checker( pThis, &LevelMutexInfo::IsValid2 );
|
||||||
(void)checker;
|
(void)checker;
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -728,7 +739,8 @@ bool LevelMutexInfo::IsRecentLock( std::size_t count ) const volatile
|
||||||
bool LevelMutexInfo::IsLockedByAnotherThread( void ) const volatile
|
bool LevelMutexInfo::IsLockedByAnotherThread( void ) const volatile
|
||||||
{
|
{
|
||||||
LOKI_MUTEX_DEBUG_CODE(
|
LOKI_MUTEX_DEBUG_CODE(
|
||||||
CheckFor::NoThrowOrChange checker( this, &LevelMutexInfo::IsValid );
|
const LevelMutexInfo * pThis = const_cast< const LevelMutexInfo * >( this );
|
||||||
|
CheckFor::NoThrowOrChange checker( pThis, &LevelMutexInfo::IsValid2 );
|
||||||
(void)checker;
|
(void)checker;
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -743,7 +755,7 @@ bool LevelMutexInfo::IsLockedByAnotherThread( void ) const volatile
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool LevelMutexInfo::PostLockValidator( void ) const volatile
|
bool LevelMutexInfo::PostLockValidator( void ) const
|
||||||
{
|
{
|
||||||
assert( 0 == m_count );
|
assert( 0 == m_count );
|
||||||
assert( nullptr == m_previous );
|
assert( nullptr == m_previous );
|
||||||
|
@ -756,9 +768,18 @@ bool LevelMutexInfo::PostLockValidator( void ) const volatile
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void LevelMutexInfo::PostLock( void ) volatile
|
void LevelMutexInfo::PostLock( void ) volatile
|
||||||
|
{
|
||||||
|
LevelMutexInfo * pThis = const_cast< LevelMutexInfo * >( this );
|
||||||
|
pThis->PostLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void LevelMutexInfo::PostLock( void )
|
||||||
{
|
{
|
||||||
LOKI_MUTEX_DEBUG_CODE(
|
LOKI_MUTEX_DEBUG_CODE(
|
||||||
CheckFor::NoThrow checker( this, &LevelMutexInfo::IsValid,
|
const LevelMutexInfo * pThis = const_cast< const LevelMutexInfo * >( this );
|
||||||
|
CheckFor::NoThrow checker( pThis, &LevelMutexInfo::IsValid2,
|
||||||
&LevelMutexInfo::PostLockValidator, &LevelMutexInfo::IsLockedByCurrentThreadImpl );
|
&LevelMutexInfo::PostLockValidator, &LevelMutexInfo::IsLockedByCurrentThreadImpl );
|
||||||
(void)checker;
|
(void)checker;
|
||||||
)
|
)
|
||||||
|
@ -775,7 +796,7 @@ void LevelMutexInfo::PostLock( void ) volatile
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool LevelMutexInfo::PreUnlockValidator( void ) const volatile
|
bool LevelMutexInfo::PreUnlockValidator( void ) const
|
||||||
{
|
{
|
||||||
assert( 1 == m_count );
|
assert( 1 == m_count );
|
||||||
assert( nullptr != s_currentMutex );
|
assert( nullptr != s_currentMutex );
|
||||||
|
@ -790,9 +811,10 @@ bool LevelMutexInfo::PreUnlockValidator( void ) const volatile
|
||||||
void LevelMutexInfo::PreUnlock( void ) volatile
|
void LevelMutexInfo::PreUnlock( void ) volatile
|
||||||
{
|
{
|
||||||
LOKI_MUTEX_DEBUG_CODE(
|
LOKI_MUTEX_DEBUG_CODE(
|
||||||
|
const LevelMutexInfo * pThis = const_cast< const LevelMutexInfo * >( this );
|
||||||
// This must use CheckFor::Invariants instead of CheckFor::NoThrow because the
|
// This must use CheckFor::Invariants instead of CheckFor::NoThrow because the
|
||||||
// function gets called when MultiLock has to clean up after an exception.
|
// function gets called when MultiLock has to clean up after an exception.
|
||||||
CheckFor::Invariants checker( this, &LevelMutexInfo::IsValid,
|
CheckFor::Invariants checker( pThis, &LevelMutexInfo::IsValid2,
|
||||||
&LevelMutexInfo::PreUnlockValidator, &LevelMutexInfo::IsNotLockedByCurrentThread );
|
&LevelMutexInfo::PreUnlockValidator, &LevelMutexInfo::IsNotLockedByCurrentThread );
|
||||||
(void)checker;
|
(void)checker;
|
||||||
)
|
)
|
||||||
|
@ -812,7 +834,8 @@ void LevelMutexInfo::PreUnlock( void ) volatile
|
||||||
MutexErrors::Type LevelMutexInfo::PreLockCheck( bool forTryLock ) volatile
|
MutexErrors::Type LevelMutexInfo::PreLockCheck( bool forTryLock ) volatile
|
||||||
{
|
{
|
||||||
LOKI_MUTEX_DEBUG_CODE(
|
LOKI_MUTEX_DEBUG_CODE(
|
||||||
CheckFor::NoThrow checker( this, &LevelMutexInfo::IsValid );
|
const LevelMutexInfo * pThis = const_cast< const LevelMutexInfo * >( this );
|
||||||
|
CheckFor::NoThrow checker( pThis, &LevelMutexInfo::IsValid2 );
|
||||||
(void)checker;
|
(void)checker;
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -849,7 +872,8 @@ MutexErrors::Type LevelMutexInfo::PreLockCheck( bool forTryLock ) volatile
|
||||||
MutexErrors::Type LevelMutexInfo::PreUnlockCheck( void ) volatile
|
MutexErrors::Type LevelMutexInfo::PreUnlockCheck( void ) volatile
|
||||||
{
|
{
|
||||||
LOKI_MUTEX_DEBUG_CODE(
|
LOKI_MUTEX_DEBUG_CODE(
|
||||||
CheckFor::NoThrow checker( this, &LevelMutexInfo::IsValid );
|
const LevelMutexInfo * pThis = const_cast< const LevelMutexInfo * >( this );
|
||||||
|
CheckFor::NoThrow checker( pThis, &LevelMutexInfo::IsValid2 );
|
||||||
(void)checker;
|
(void)checker;
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue