From: <ric...@us...> - 2008-11-10 06:48:43
|
Revision: 905 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=905&view=rev Author: rich_sposato Date: 2008-11-10 06:48:38 +0000 (Mon, 10 Nov 2008) Log Message: ----------- Removed thread_local storage qualifier for GCC. Add ctor initializer for GCC. Modified Paths: -------------- trunk/src/LevelMutex.cpp Modified: trunk/src/LevelMutex.cpp =================================================================== --- trunk/src/LevelMutex.cpp 2008-11-10 05:59:59 UTC (rev 904) +++ trunk/src/LevelMutex.cpp 2008-11-10 06:48:38 UTC (rev 905) @@ -4,9 +4,9 @@ // Copyright (c) 2008 Richard Sposato // The copyright on this file is protected under the terms of the MIT license. // -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this +// Permission to use, copy, modify, distribute and sell this software for any +// purpose is hereby granted without fee, provided that the above copyright +// notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // // The author makes no representations about the suitability of this software @@ -33,7 +33,7 @@ #define nullptr 0 -LOKI_THREAD_LOCAL volatile ::Loki::LevelMutexInfo * ::Loki::LevelMutexInfo::s_currentMutex = nullptr; +volatile ::Loki::LevelMutexInfo * ::Loki::LevelMutexInfo::s_currentMutex = nullptr; unsigned int ::Loki::MutexSleepWaits::sleepTime = 1; @@ -960,6 +960,7 @@ // ---------------------------------------------------------------------------- MutexException::MutexException( const MutexException & that ) throw () : + ::std::exception( that ), m_message( that.m_message ), m_level( that.m_level ), m_reason( that.m_reason ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <syn...@us...> - 2008-12-10 19:47:44
|
Revision: 907 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=907&view=rev Author: syntheticpp Date: 2008-12-10 19:47:33 +0000 (Wed, 10 Dec 2008) Log Message: ----------- gcc 4.2 fix Modified Paths: -------------- trunk/src/LevelMutex.cpp Modified: trunk/src/LevelMutex.cpp =================================================================== --- trunk/src/LevelMutex.cpp 2008-11-12 07:00:16 UTC (rev 906) +++ trunk/src/LevelMutex.cpp 2008-12-10 19:47:33 UTC (rev 907) @@ -33,7 +33,7 @@ #define nullptr 0 -volatile ::Loki::LevelMutexInfo * ::Loki::LevelMutexInfo::s_currentMutex = nullptr; +LOKI_THREAD_LOCAL volatile ::Loki::LevelMutexInfo * ::Loki::LevelMutexInfo::s_currentMutex = nullptr; unsigned int ::Loki::MutexSleepWaits::sleepTime = 1; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <syn...@us...> - 2009-01-26 19:58:12
|
Revision: 951 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=951&view=rev Author: syntheticpp Date: 2009-01-26 19:58:04 +0000 (Mon, 26 Jan 2009) Log Message: ----------- Apple fix Modified Paths: -------------- trunk/src/LevelMutex.cpp Modified: trunk/src/LevelMutex.cpp =================================================================== --- trunk/src/LevelMutex.cpp 2009-01-26 19:45:54 UTC (rev 950) +++ trunk/src/LevelMutex.cpp 2009-01-26 19:58:04 UTC (rev 951) @@ -20,7 +20,7 @@ // ---------------------------------------------------------------------------- -#if !defined(__CYGWIN__) || (defined(__CYGWIN__) && __GNUC__ > 3) +#if (!defined(__CYGWIN__) || (defined(__CYGWIN__) && __GNUC__ > 3)) && !defined(__APPLE__) #include <loki/LevelMutex.h> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-03-04 07:13:10
|
Revision: 995 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=995&view=rev Author: rich_sposato Date: 2009-03-04 07:13:07 +0000 (Wed, 04 Mar 2009) Log Message: ----------- Fixed bug 2656893. Removed redundant assertions. Modified Paths: -------------- trunk/src/LevelMutex.cpp Modified: trunk/src/LevelMutex.cpp =================================================================== --- trunk/src/LevelMutex.cpp 2009-03-03 22:14:49 UTC (rev 994) +++ trunk/src/LevelMutex.cpp 2009-03-04 07:13:07 UTC (rev 995) @@ -574,7 +574,6 @@ bool LevelMutexInfo::IsLockedByCurrentThread( void ) const volatile { - assert( IsValid() ); LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) if ( !IsLocked() ) @@ -593,7 +592,6 @@ bool LevelMutexInfo::IsRecentLock( void ) const volatile { - assert( IsValid() ); LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) if ( 0 == m_count ) @@ -615,7 +613,6 @@ bool LevelMutexInfo::IsRecentLock( unsigned int count ) const volatile { - assert( IsValid() ); LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) if ( 0 == count ) @@ -636,7 +633,6 @@ bool LevelMutexInfo::IsLockedByAnotherThread( void ) const volatile { - assert( IsValid() ); LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) if ( !IsLocked() ) @@ -652,12 +648,11 @@ void LevelMutexInfo::PostLock( void ) volatile { - assert( IsValid() ); + LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) assert( 0 == m_count ); assert( nullptr == m_previous ); assert( this != s_currentMutex ); assert( !IsLockedByCurrentThread() ); - LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) m_count = 1; m_previous = s_currentMutex; @@ -668,12 +663,11 @@ void LevelMutexInfo::PreUnlock( void ) volatile { - assert( IsValid() ); + LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) assert( 1 == m_count ); assert( nullptr != s_currentMutex ); assert( this == s_currentMutex ); assert( IsLockedByCurrentThread() ); - LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) s_currentMutex = m_previous; m_previous = nullptr; @@ -684,7 +678,6 @@ MutexErrors::Type LevelMutexInfo::PreLockCheck( bool forTryLock ) volatile { - assert( IsValid() ); LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) const unsigned int currentLevel = GetCurrentThreadsLevel(); @@ -719,7 +712,6 @@ MutexErrors::Type LevelMutexInfo::PreUnlockCheck( void ) volatile { - assert( IsValid() ); LOKI_MUTEX_DEBUG_CODE( Checker checker( this ); (void)checker; ) if ( 0 == m_count ) @@ -760,9 +752,9 @@ unsigned int level ) { if ( ( error == MutexErrors::LevelTooHigh ) - && ( error == MutexErrors::LevelTooLow ) ) + || ( error == MutexErrors::LevelTooLow ) ) { - throw MutexException( "Error occurred using mutex.", level, error ); + throw MutexException( "Design error! Program used mutexes in wrong order.", level, error ); } return error; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-09-29 19:02:51
|
Revision: 1026 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1026&view=rev Author: rich_sposato Date: 2009-09-29 19:02:43 +0000 (Tue, 29 Sep 2009) Log Message: ----------- Changed #if statement used to decide to compile code. Modified Paths: -------------- trunk/src/LevelMutex.cpp Modified: trunk/src/LevelMutex.cpp =================================================================== --- trunk/src/LevelMutex.cpp 2009-09-26 23:49:05 UTC (rev 1025) +++ trunk/src/LevelMutex.cpp 2009-09-29 19:02:43 UTC (rev 1026) @@ -20,8 +20,26 @@ // ---------------------------------------------------------------------------- -#if (!defined(__CYGWIN__) || (defined(__CYGWIN__) && __GNUC__ > 3)) && !defined(__APPLE__) +// First assume the compiler does allow thread-local storage by #defining the +// macro which allows compiler to see the code inside this file. +// Then #undefine the macro for compilers which are known for not supporting +// thread-local storage. +#define COMPILER_ALLOWS_THREAD_LOCAL_STORAGE 1 +// The __APPLE__ macro does not refer to a compiler, but to the Apple OSX operating system. +#if defined( __APPLE__ ) + #warning "GCC for Apple does not allow thread_local storage, so you can not use Loki::LevelMutex." + #undef COMPILER_ALLOWS_THREAD_LOCAL_STORAGE +#endif + +#if ( defined( __CYGWIN__ ) && ( __GNUC__ <= 3 ) ) + #warning "Older versions of GCC for Cygwin do not allow thread_local storage, so you can not use Loki::LevelMutex." + #undef COMPILER_ALLOWS_THREAD_LOCAL_STORAGE +#endif + +#if defined( COMPILER_ALLOWS_THREAD_LOCAL_STORAGE ) + + #include <loki/LevelMutex.h> #include <algorithm> @@ -1143,6 +1161,4 @@ } // end namespace Loki - -#endif - +#endif // #if defined( COMPILER_ALLOWS_THREAD_LOCAL_STORAGE ) 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:45:29
|
Revision: 1182 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1182&view=rev Author: rich_sposato Date: 2012-04-03 05:45:23 +0000 (Tue, 03 Apr 2012) Log Message: ----------- Added overloaded version of file. Modified Paths: -------------- trunk/src/LevelMutex.cpp Modified: trunk/src/LevelMutex.cpp =================================================================== --- trunk/src/LevelMutex.cpp 2012-04-02 06:07:08 UTC (rev 1181) +++ trunk/src/LevelMutex.cpp 2012-04-03 05:45:23 UTC (rev 1182) @@ -671,6 +671,14 @@ bool LevelMutexInfo::IsNotLockedByCurrentThread( void ) const volatile { + const LevelMutexInfo * pThis = const_cast< const LevelMutexInfo * >( this ); + return pThis->IsNotLockedByCurrentThread(); +} + +// ---------------------------------------------------------------------------- + +bool LevelMutexInfo::IsNotLockedByCurrentThread( void ) const +{ if ( !IsLocked() ) return true; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-10-01 17:54:47
|
Revision: 1027 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1027&view=rev Author: rich_sposato Date: 2009-10-01 17:54:38 +0000 (Thu, 01 Oct 2009) Log Message: ----------- Replaced sleep with usleep. Modified Paths: -------------- trunk/src/LevelMutex.cpp Modified: trunk/src/LevelMutex.cpp =================================================================== --- trunk/src/LevelMutex.cpp 2009-09-29 19:02:43 UTC (rev 1026) +++ trunk/src/LevelMutex.cpp 2009-10-01 17:54:38 UTC (rev 1027) @@ -40,8 +40,11 @@ #if defined( COMPILER_ALLOWS_THREAD_LOCAL_STORAGE ) -#include <loki/LevelMutex.h> +#include "../include/loki/LevelMutex.h" +#if !defined( _MSC_VER ) + #include <unistd.h> // needed for usleep function. +#endif #include <algorithm> #include <cerrno> @@ -784,7 +787,9 @@ #if defined( _MSC_VER ) ::SleepEx( sleepTime, true ); #else - ::sleep( sleepTime ); + if ( 0 == sleepTime ) + sleepTime = 1; + ::usleep( sleepTime * 1000 ); #endif } @@ -911,29 +916,28 @@ // ---------------------------------------------------------------------------- -#if defined( _MSC_VER ) - SleepLevelMutex::SleepLevelMutex( unsigned int level ) : SpinLevelMutex( level ), - m_sleepTime( 1 ), - m_wakable( true ) + m_sleepTime( 1 ) +#if defined( _MSC_VER ) + , m_wakable( true ) +#endif { } // ---------------------------------------------------------------------------- -#else - SleepLevelMutex::SleepLevelMutex( unsigned int level, unsigned int sleepTime ) : SpinLevelMutex( level ), - m_sleepTime( sleepTime / 1000 ) + m_sleepTime( sleepTime ) +#if defined( _MSC_VER ) + , m_wakable( true ) +#endif { if ( 0 == m_sleepTime ) - m_sleepTime = 1; // Can't have a resolution less than 1 second. + m_sleepTime = 1; // Can't have a resolution less than 1 millisecond. } -#endif - // ---------------------------------------------------------------------------- SleepLevelMutex::~SleepLevelMutex( void ) @@ -953,7 +957,7 @@ #if defined( _MSC_VER ) ::SleepEx( m_sleepTime, m_wakable ); #else - ::sleep( m_sleepTime ); + ::usleep( m_sleepTime * 1000 ); #endif } return MutexErrors::Success; 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:37
|
Revision: 1176 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1176&view=rev Author: rich_sposato Date: 2011-11-07 23:55:30 +0000 (Mon, 07 Nov 2011) Log Message: ----------- Added Memento class to prove strong exception safety. Removed useless lines. Modified Paths: -------------- trunk/src/LevelMutex.cpp Modified: trunk/src/LevelMutex.cpp =================================================================== --- trunk/src/LevelMutex.cpp 2011-11-07 23:54:58 UTC (rev 1175) +++ trunk/src/LevelMutex.cpp 2011-11-07 23:55:30 UTC (rev 1176) @@ -232,6 +232,38 @@ // ---------------------------------------------------------------------------- +LevelMutexInfo::Memento::Memento( const volatile LevelMutexInfo & mutex ) : + m_level( mutex.m_level ), + m_count( mutex.m_count ), + m_previous( mutex.m_previous ), + m_locked( mutex.IsLockedByCurrentThreadImpl() ) +{ + assert( this != nullptr ); +} + +// ---------------------------------------------------------------------------- + +bool LevelMutexInfo::Memento::operator == ( const volatile LevelMutexInfo & mutex ) const +{ + assert( this != nullptr ); + + if ( m_locked && mutex.IsLockedByCurrentThreadImpl() ) + { + // If the current thread still has a lock on the mutex, then make + // sure no values have changed. + if ( m_level != mutex.m_level ) + return false; + if ( m_count != mutex.m_count ) + return false; + if ( m_previous != mutex.m_previous ) + return false; + } + + return true; +} + +// ---------------------------------------------------------------------------- + LevelMutexInfo::MutexUndoer::MutexUndoer( MutexContainer & mutexes ) : m_mutexes( mutexes ), m_here( mutexes.end() ) @@ -572,6 +604,14 @@ // ---------------------------------------------------------------------------- +bool LevelMutexInfo::IsValid( void ) const +{ + const volatile LevelMutexInfo * pThis = const_cast< const volatile LevelMutexInfo * >( this ); + return pThis->IsValid(); +} + +// ---------------------------------------------------------------------------- + void LevelMutexInfo::IncrementCount( void ) volatile { assert( IsValid() ); @@ -592,8 +632,20 @@ bool LevelMutexInfo::IsLockedByCurrentThread( void ) const volatile { - LOKI_MUTEX_DEBUG_CODE( CheckFor::NoChangeOrThrow checker( this, &IsValid() ); (void)checker; ) + // This function could call CheckFor::NoThrowOrChange - except that this function + // gets called by various functions that are called to clean up after an exception + // is thrown + LOKI_MUTEX_DEBUG_CODE( + CheckFor::NoChange checker( this, &LevelMutexInfo::IsValid ); + (void)checker; + ) + return IsLockedByCurrentThreadImpl(); +} +// ---------------------------------------------------------------------------- + +bool LevelMutexInfo::IsLockedByCurrentThreadImpl( void ) const volatile +{ if ( !IsLocked() ) return false; const volatile LevelMutexInfo * mutex = s_currentMutex; @@ -608,9 +660,30 @@ // ---------------------------------------------------------------------------- +bool LevelMutexInfo::IsNotLockedByCurrentThread( void ) const volatile +{ + if ( !IsLocked() ) + return true; + + const volatile LevelMutexInfo * mutex = s_currentMutex; + while ( nullptr != mutex ) + { + if ( this == mutex ) + return false; + mutex = mutex->m_previous; + } + + return true; +} + +// ---------------------------------------------------------------------------- + bool LevelMutexInfo::IsRecentLock( void ) const volatile { - LOKI_MUTEX_DEBUG_CODE( CheckFor::NoChangeOrThrow checker( this, &IsValid() ); (void)checker; ) + LOKI_MUTEX_DEBUG_CODE( + CheckFor::NoThrowOrChange checker( this, &LevelMutexInfo::IsValid ); + (void)checker; + ) if ( 0 == m_count ) return false; @@ -631,7 +704,10 @@ bool LevelMutexInfo::IsRecentLock( std::size_t count ) const volatile { - LOKI_MUTEX_DEBUG_CODE( CheckFor::NoChangeOrThrow checker( this, &IsValid() ); (void)checker; ) + LOKI_MUTEX_DEBUG_CODE( + CheckFor::NoThrowOrChange checker( this, &LevelMutexInfo::IsValid ); + (void)checker; + ) if ( 0 == count ) return false; @@ -651,7 +727,10 @@ bool LevelMutexInfo::IsLockedByAnotherThread( void ) const volatile { - LOKI_MUTEX_DEBUG_CODE( CheckFor::NoChangeOrThrow checker( this, &IsValid() ); (void)checker; ) + LOKI_MUTEX_DEBUG_CODE( + CheckFor::NoThrowOrChange checker( this, &LevelMutexInfo::IsValid ); + (void)checker; + ) if ( !IsLocked() ) return false; @@ -664,14 +743,31 @@ // ---------------------------------------------------------------------------- -void LevelMutexInfo::PostLock( void ) volatile +bool LevelMutexInfo::PostLockValidator( void ) const volatile { - LOKI_MUTEX_DEBUG_CODE( CheckFor::NoThrow checker( this, &IsValid() ); (void)checker; ) assert( 0 == m_count ); assert( nullptr == m_previous ); assert( this != s_currentMutex ); assert( !IsLockedByCurrentThread() ); + return true; +} + +// ---------------------------------------------------------------------------- + +void LevelMutexInfo::PostLock( void ) volatile +{ + LOKI_MUTEX_DEBUG_CODE( + CheckFor::NoThrow checker( this, &LevelMutexInfo::IsValid, + &LevelMutexInfo::PostLockValidator, &LevelMutexInfo::IsLockedByCurrentThreadImpl ); + (void)checker; + ) + + /** Of the three data members PostLock must modify, it should change the count + before changing the other two. The IsLocked function uses the count to see if + the mutex is locked, so changing this first stops other threads from trying to + lock the object before this thread can modify the other two data members. + */ m_count = 1; m_previous = s_currentMutex; s_currentMutex = this; @@ -679,14 +775,33 @@ // ---------------------------------------------------------------------------- -void LevelMutexInfo::PreUnlock( void ) volatile +bool LevelMutexInfo::PreUnlockValidator( void ) const volatile { - LOKI_MUTEX_DEBUG_CODE( CheckFor::NoThrow checker( this, &IsValid() ); (void)checker; ) assert( 1 == m_count ); assert( nullptr != s_currentMutex ); assert( this == s_currentMutex ); assert( IsLockedByCurrentThread() ); + return true; +} + +// ---------------------------------------------------------------------------- + +void LevelMutexInfo::PreUnlock( void ) volatile +{ + LOKI_MUTEX_DEBUG_CODE( + // This must use CheckFor::Invariants instead of CheckFor::NoThrow because the + // function gets called when MultiLock has to clean up after an exception. + CheckFor::Invariants checker( this, &LevelMutexInfo::IsValid, + &LevelMutexInfo::PreUnlockValidator, &LevelMutexInfo::IsNotLockedByCurrentThread ); + (void)checker; + ) + + /** Of the three data members PostLock must modify, it should change the count + after changing the other two. The IsLocked function uses the count to see if + the mutex is locked, so changing this last stops other threads from trying to + lock the object before this thread can modify the other two data members. + */ s_currentMutex = m_previous; m_previous = nullptr; m_count = 0; @@ -696,7 +811,10 @@ MutexErrors::Type LevelMutexInfo::PreLockCheck( bool forTryLock ) volatile { - LOKI_MUTEX_DEBUG_CODE( CheckFor::NoThrow checker( this, &IsValid() ); (void)checker; ) + LOKI_MUTEX_DEBUG_CODE( + CheckFor::NoThrow checker( this, &LevelMutexInfo::IsValid ); + (void)checker; + ) const unsigned int currentLevel = GetCurrentThreadsLevel(); if ( currentLevel < LevelMutexInfo::GetLevel() ) @@ -730,7 +848,10 @@ MutexErrors::Type LevelMutexInfo::PreUnlockCheck( void ) volatile { - LOKI_MUTEX_DEBUG_CODE( CheckFor::NoThrow checker( this, &IsValid() ); (void)checker; ) + LOKI_MUTEX_DEBUG_CODE( + CheckFor::NoThrow checker( this, &LevelMutexInfo::IsValid ); + (void)checker; + ) if ( 0 == m_count ) return MutexErrors::WasntLocked; @@ -803,9 +924,6 @@ switch ( result ) { case 0: -//#if defined( DEBUG_LOKI_LEVEL_MUTEX ) -// cout << __FUNCTION__ << '\t' << __LINE__ << endl; -//#endif return; case EBUSY: throw MutexException( "pthread mutex already initialized!", @@ -842,9 +960,6 @@ #if defined( _MSC_VER ) ::DeleteCriticalSection( &m_mutex ); #else -//#if defined( DEBUG_LOKI_LEVEL_MUTEX ) -// cout << __FUNCTION__ << '\t' << __LINE__ << endl; -//#endif ::pthread_mutex_destroy( &m_mutex ); #endif } @@ -868,9 +983,6 @@ switch ( result ) { case 0: -//#if defined( DEBUG_LOKI_LEVEL_MUTEX ) -// cout << __FUNCTION__ << '\t' << __LINE__ << endl; -//#endif break; default: case EINVAL: @@ -911,9 +1023,6 @@ switch ( result ) { case 0: -//#if defined( DEBUG_LOKI_LEVEL_MUTEX ) -// cout << __FUNCTION__ << '\t' << __LINE__ << endl; -//#endif return MutexErrors::Success; default: case EBUSY: @@ -943,9 +1052,6 @@ if ( EPERM == result ) throw MutexException( "current thread did not lock this pthread mutex!", GetLevel(), MutexErrors::NotLockedByThread ); -//#if defined( DEBUG_LOKI_LEVEL_MUTEX ) -// cout << __FUNCTION__ << '\t' << __LINE__ << endl; -//#endif #endif return MutexErrors::Success; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |