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:
rich_sposato 2012-04-02 06:05:04 +00:00
parent 42786afc4b
commit f306c39e6e
2 changed files with 60 additions and 26 deletions

View file

@ -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;

View file

@ -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;
) )