From: <ric...@us...> - 2009-09-26 23:07:17
|
Revision: 1024 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1024&view=rev Author: rich_sposato Date: 2009-09-26 23:07:10 +0000 (Sat, 26 Sep 2009) Log Message: ----------- Replaced assert( IsValid() ) with checker's call to IsValid. Modified Paths: -------------- trunk/include/loki/LevelMutex.h Modified: trunk/include/loki/LevelMutex.h =================================================================== --- trunk/include/loki/LevelMutex.h 2009-09-26 21:10:43 UTC (rev 1023) +++ trunk/include/loki/LevelMutex.h 2009-09-26 23:07:10 UTC (rev 1024) @@ -280,8 +280,9 @@ { public: inline explicit Checker( const volatile LevelMutexInfo * mutex ) : - m_mutex( mutex ) {} - inline ~Checker( void ) { m_mutex->IsValid(); } + m_mutex( mutex ) { Check(); } + inline ~Checker( void ) { Check(); } + inline bool Check( void ) const { return m_mutex->IsValid(); } private: Checker( void ); Checker( const Checker & ); @@ -782,7 +783,6 @@ virtual MutexErrors::Type TryLock( void ) volatile { - assert( IsValid() ); LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) MutexErrors::Type result = LevelMutexInfo::PreLockCheck( true ); @@ -804,7 +804,6 @@ virtual MutexErrors::Type Lock( void ) volatile { - assert( IsValid() ); LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) MutexErrors::Type result = LevelMutexInfo::PreLockCheck( false ); @@ -824,7 +823,6 @@ virtual MutexErrors::Type Lock( unsigned int milliSeconds ) volatile { - assert( IsValid() ); LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) MutexErrors::Type result = LevelMutexInfo::PreLockCheck( false ); @@ -860,7 +858,6 @@ virtual MutexErrors::Type Unlock( void ) volatile { - assert( IsValid() ); LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) MutexErrors::Type result = LevelMutexInfo::PreUnlockCheck(); @@ -906,7 +903,6 @@ */ virtual MutexErrors::Type LockThis( void ) volatile { - assert( IsValid() ); LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) assert( this != LevelMutexInfo::GetCurrentMutex() ); @@ -927,7 +923,6 @@ */ virtual MutexErrors::Type LockThis( unsigned int milliSeconds ) volatile { - assert( IsValid() ); LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) clock_t timeOut = clock() + milliSeconds; @@ -953,9 +948,8 @@ */ virtual MutexErrors::Type UnlockThis( void ) volatile { - assert( IsValid() ); - assert( NULL != LevelMutexInfo::GetCurrentMutex() ); LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) + assert( NULL != LevelMutexInfo::GetCurrentMutex() ); if ( 1 < LevelMutexInfo::GetLockCount() ) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2011-06-21 08:08:24
|
Revision: 1088 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1088&view=rev Author: rich_sposato Date: 2011-06-21 08:08:18 +0000 (Tue, 21 Jun 2011) Log Message: ----------- Moved location of #include statements inside file. Modified Paths: -------------- trunk/include/loki/LevelMutex.h Modified: trunk/include/loki/LevelMutex.h =================================================================== --- trunk/include/loki/LevelMutex.h 2011-06-21 03:35:30 UTC (rev 1087) +++ trunk/include/loki/LevelMutex.h 2011-06-21 08:08:18 UTC (rev 1088) @@ -24,17 +24,17 @@ // ---------------------------------------------------------------------------- -#include <vector> -#include <assert.h> -#include <time.h> - #if defined( _MSC_VER ) #include <Windows.h> #else #include <pthread.h> #endif -#if !defined(_WIN32) && !defined(_WIN64) +#include <vector> +#include <assert.h> +#include <time.h> + +#if !defined( _WIN32 ) && !defined( _WIN64 ) #include <unistd.h> // declares usleep under Linux #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2011-09-06 23:01:32
|
Revision: 1089 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1089&view=rev Author: rich_sposato Date: 2011-09-06 23:01:26 +0000 (Tue, 06 Sep 2011) Log Message: ----------- Added include statement to fix bug 3399706. Modified Paths: -------------- trunk/include/loki/LevelMutex.h Modified: trunk/include/loki/LevelMutex.h =================================================================== --- trunk/include/loki/LevelMutex.h 2011-06-21 08:08:18 UTC (rev 1088) +++ trunk/include/loki/LevelMutex.h 2011-09-06 23:01:26 UTC (rev 1089) @@ -30,6 +30,7 @@ #include <pthread.h> #endif +#include <exception> #include <vector> #include <assert.h> #include <time.h> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2011-11-07 23:55:04
|
Revision: 1175 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1175&view=rev Author: rich_sposato Date: 2011-11-07 23:54:58 +0000 (Mon, 07 Nov 2011) Log Message: ----------- Added Memento class to prove strong exception safety. Modified Paths: -------------- trunk/include/loki/LevelMutex.h Modified: trunk/include/loki/LevelMutex.h =================================================================== --- trunk/include/loki/LevelMutex.h 2011-11-07 23:35:28 UTC (rev 1174) +++ trunk/include/loki/LevelMutex.h 2011-11-07 23:54:58 UTC (rev 1175) @@ -144,8 +144,10 @@ { public: - /** 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. + /** This is the default level for a thread that has not locked any mutex. The + maximum possible level for a mutex is UnlockedLevel-1, and I doubt any software + will ever have a call stack of more than 2^32-2 functions. No mutex may have a + level of UnlockedLevel. */ static const unsigned int UnlockedLevel = 0xFFFFFFFF; @@ -265,12 +267,35 @@ protected: + /// @class Memento Stores content of LevelMutexInfo so CheckFor can check invariants. + class Memento + { + public: + + explicit Memento( const volatile LevelMutexInfo & mutex ); + + bool operator == ( const volatile LevelMutexInfo & mutex ) const; + + private: + /// Level of this mutex. + const unsigned int m_level; + + /// How many times this mutex got locked. + const unsigned int m_count; + + /// Pointer to mutex locked before this one. + const volatile LevelMutexInfo * const m_previous; + + /// True if mutex was locked when Memento was constructed. + const bool m_locked; + }; + /** @note CheckFor performs validity checking in many functions to determine if the code violated any invariants, if any content changed, or if the function threw an exception. The checkers only get used in debug builds, and get optimized away in release builds. */ - typedef ::Loki::CheckFor< LevelMutexInfo > CheckFor; + typedef ::Loki::CheckFor< volatile LevelMutexInfo, Memento > CheckFor; /** @class MutexUndoer Undoes actions by MultiLock if an exception occurs. It keeps track of @@ -334,6 +359,17 @@ */ bool IsValid( void ) const volatile; + /** Returns true if no class invariant broken, otherwise asserts. This function + only gets called in debug builds. + */ + bool IsValid( void ) const; + + /// Returns true if all pre-conditions for PostLock function are valid. + bool PostLockValidator( void ) const volatile; + + /// Returns true if all pre-conditions for PreUnlock function are valid. + bool PreUnlockValidator( void ) const volatile; + private: /// Copy constructor is not implemented. @@ -359,6 +395,16 @@ /// Called only by MultiUnlock to unlock each particular mutex within a container. virtual MutexErrors::Type UnlockThis( void ) volatile = 0; + /** The actual implementation of IsLockedByCurrentThread. This does not do any + invariant checking because the functions which call it already have. + */ + bool IsLockedByCurrentThreadImpl( void ) const volatile; + + /** Does just the opposite of IsLockedByCurrentThread. Called as a post-condition + check by another function. + */ + bool IsNotLockedByCurrentThread( void ) const volatile; + /// Pointer to singly-linked list of mutexes locked by the current thread. static LOKI_THREAD_LOCAL volatile LevelMutexInfo * s_currentMutex; @@ -765,7 +811,7 @@ virtual MutexErrors::Type TryLock( void ) volatile { - LOKI_MUTEX_DEBUG_CODE( CheckFor::Invariants checker( this, &IsValid() ); (void)checker; ) + LOKI_MUTEX_DEBUG_CODE( CheckFor::NoChangeOnThrow checker( this, &IsValid ); (void)checker; ) MutexErrors::Type result = LevelMutexInfo::PreLockCheck( true ); if ( MutexErrors::Success == result ) @@ -786,7 +832,7 @@ virtual MutexErrors::Type Lock( void ) volatile { - LOKI_MUTEX_DEBUG_CODE( CheckFor::Invariants checker( this, &IsValid() ); (void)checker; ) + LOKI_MUTEX_DEBUG_CODE( CheckFor::NoChangeOnThrow checker( this, &IsValid ); (void)checker; ) MutexErrors::Type result = LevelMutexInfo::PreLockCheck( false ); if ( MutexErrors::Success == result ) @@ -805,7 +851,7 @@ virtual MutexErrors::Type Lock( unsigned int milliSeconds ) volatile { - LOKI_MUTEX_DEBUG_CODE( CheckFor::Invariants checker( this, &IsValid() ); (void)checker; ) + LOKI_MUTEX_DEBUG_CODE( CheckFor::NoChangeOnThrow checker( this, &IsValid ); (void)checker; ) MutexErrors::Type result = LevelMutexInfo::PreLockCheck( false ); if ( MutexErrors::Success == result ) @@ -840,7 +886,7 @@ virtual MutexErrors::Type Unlock( void ) volatile { - LOKI_MUTEX_DEBUG_CODE( CheckFor::Invariants checker( this, &IsValid() ); (void)checker; ) + LOKI_MUTEX_DEBUG_CODE( CheckFor::NoChangeOnThrow checker( this, &IsValid ); (void)checker; ) MutexErrors::Type result = LevelMutexInfo::PreUnlockCheck(); if ( MutexErrors::Success == result ) @@ -885,7 +931,7 @@ */ virtual MutexErrors::Type LockThis( void ) volatile { - LOKI_MUTEX_DEBUG_CODE( CheckFor::Invariants checker( this, &IsValid() ); (void)checker; ) + LOKI_MUTEX_DEBUG_CODE( CheckFor::NoChangeOnThrow checker( this, &IsValid ); (void)checker; ) assert( this != LevelMutexInfo::GetCurrentMutex() ); const MutexErrors::Type result = m_mutex.Lock(); @@ -905,7 +951,7 @@ */ virtual MutexErrors::Type LockThis( unsigned int milliSeconds ) volatile { - LOKI_MUTEX_DEBUG_CODE( CheckFor::Invariants checker( this, &IsValid() ); (void)checker; ) + LOKI_MUTEX_DEBUG_CODE( CheckFor::NoChangeOnThrow checker( this, &IsValid ); (void)checker; ) clock_t timeOut = clock() + milliSeconds; while ( clock() < timeOut ) @@ -930,7 +976,7 @@ */ virtual MutexErrors::Type UnlockThis( void ) volatile { - LOKI_MUTEX_DEBUG_CODE( CheckFor::Invariants checker( this, &IsValid() ); (void)checker; ) + LOKI_MUTEX_DEBUG_CODE( CheckFor::NoChangeOnThrow checker( this, &IsValid ); (void)checker; ) assert( NULL != LevelMutexInfo::GetCurrentMutex() ); if ( 1 < LevelMutexInfo::GetLockCount() ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2012-04-03 05:47:02
|
Revision: 1183 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1183&view=rev Author: rich_sposato Date: 2012-04-03 05:46:56 +0000 (Tue, 03 Apr 2012) Log Message: ----------- Made documentation comment consistent. Modified Paths: -------------- trunk/include/loki/LevelMutex.h Modified: trunk/include/loki/LevelMutex.h =================================================================== --- trunk/include/loki/LevelMutex.h 2012-04-03 05:45:23 UTC (rev 1182) +++ trunk/include/loki/LevelMutex.h 2012-04-03 05:46:56 UTC (rev 1183) @@ -718,8 +718,8 @@ either pthreads or the Windows CRITICAL_SECTION. If you want to use a mutex mechanism besides one of those, then all you have to do is provide a class which wraps the mutex and implements these functions. - explicit SpinLevelMutex( unsigned int level ); - virtual ~SpinLevelMutex( void ); + explicit MutexPolicy( unsigned int level ); + virtual ~MutexPolicy( void ); virtual MutexErrors::Type Lock( void ) volatile; virtual MutexErrors::Type TryLock( void ) volatile; virtual MutexErrors::Type Unlock( void ) volatile; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |