/* $Revision: 14 $ $Date: 9/10/03 15:44 $ Copyright © 2001-2003, FSL Technologies Limited. Contact "http://fost3.fsltech.com". */ #include "stdafx.h" #define VC_EXTRALEAN #include #include #include #include #include #include using namespace std; using namespace FSLib; namespace { Revision c_revision( L"$Archive: /FOST.3/F3Util/locks.cpp $", __DATE__, L"$Revision: 14 $", L"$Date: 9/10/03 15:44 $" ); const wchar_t c_lockTimeoutMsg[]=L"Timeout attempting to gain lock on a shared resource."; } /* FSLib::Exceptions::LockTimeout */ inline FSLib::Exceptions::LockTimeout::LockTimeout() : FSLib::Exceptions::Exception() { } inline FSLib::Exceptions::LockTimeout::LockTimeout( const FSLib::wstring &e ) : FSLib::Exceptions::Exception( e ) { } inline const wchar_t * const FSLib::Exceptions::LockTimeout::message() const { return c_lockTimeoutMsg; } /* Semaphore */ Semaphore::Semaphore( long max ) : m_semaphore( new CSemaphore( max, max ) ), m_max( max ) { } Semaphore::~Semaphore() { try { m_semaphore.reset(); } catch ( exception & ) { absorbException(); } } inline long Semaphore::max() const { return m_max; } Semaphore::Lock::Lock( Semaphore &s ) : m_locks( new boost::scoped_ptr< CSingleLock >[ 1 ] ) { m_locks[ 0 ].reset( new CSingleLock( s.m_semaphore.get(), false ) ); m_locks[ 0 ]->Lock( 10000 ); if ( !m_locks[ 0 ]->IsLocked() ) { throw FSLib::Exceptions::LockTimeout(); } } Semaphore::Lock::Lock( Semaphore &s, int locks ) : m_locks( new boost::scoped_ptr< CSingleLock >[ locks ] ) { if ( locks > s.max() ) { throw FSLib::Exceptions::LockTimeout( L"Timeout guarantee as more locks requested than available" ); } else { for ( int a( 0 ); a != locks; ++a ) { // Must obtain a lock here first or a race condition could ensue // This happens when two threads request more locks than are available // If the locks are split between the threads then they could lock each other out Mutex::Lock lock( s.m_multiAcquire ); m_locks[ a ].reset( new CSingleLock( s.m_semaphore.get(), false ) ); m_locks[ a ]->Lock( 10000 ); if ( !m_locks[ a ]->IsLocked() ){ throw FSLib::Exceptions::LockTimeout(); } } } } Semaphore::Lock::~Lock() { try { m_locks.reset(); } catch ( exception & ) { absorbException(); } } /* Mutex */ Mutex::Mutex() : m_mutex( new CMutex() ) { } Mutex::~Mutex() { try { m_mutex.reset(); } catch ( exception & ) { absorbException(); } } Mutex::Lock::Lock( Mutex &mutex ) : m_lock( new CSingleLock( mutex.m_mutex.get(), false ) ) { m_lock->Lock( 10000 ); if ( !m_lock->IsLocked() ) { throw FSLib::Exceptions::LockTimeout(); } } Mutex::Lock::~Lock() { try { m_lock.reset(); } catch ( exception & ) { absorbException(); } } /* ExclusiveWrite */ inline ExclusiveWrite::ExclusiveWrite() : m_semaphore( 5 ) { } inline ExclusiveWrite::ExclusiveWrite( unsigned int r ) : m_semaphore( r ) { } inline ExclusiveWrite::WriteLock::WriteLock( ExclusiveWrite &exw ) { m_writeLock.reset( new Mutex::Lock( exw.m_mutex ) ); m_readLock.reset( new Semaphore::Lock( exw.m_semaphore, exw.m_semaphore.max() ) ); } inline ExclusiveWrite::WriteLock::~WriteLock() { try { m_writeLock.reset(); m_readLock.reset(); } catch ( exception & ) { absorbException(); } } inline ExclusiveWrite::ReadLock::ReadLock( ExclusiveWrite &exw ) : m_lock( exw.m_semaphore ) { } /* $History: locks.cpp $ * * ***************** Version 14 ***************** * User: Kirit Date: 9/10/03 Time: 15:44 * Updated in $/FOST.3/F3Util * Headers re-arranged to give a proper SDK feel and to make determination * of required headers simpler. * * ***************** Version 12 ***************** * User: Kirit Date: 3/10/03 Time: 16:09 * Updated in $/FOST/Cpp/FSCppUtil * Added stdafx.h and stdafx.cpp pre-compiled header support. * * ***************** Version 11 ***************** * User: Kirit Date: 7/05/02 Time: 12:01 * Updated in $/FOST/Cpp/FSCppUtil * Wrapped std::basic_string<> in order to change the copy semantics to * stop the problems with using C++ in the COM layer for IIS. * * ***************** Version 10 ***************** * User: Kirit Date: 28/04/02 Time: 21:18 * Updated in $/FOST/Cpp/FSCppUtil * Added support for converting Windows Structured Exceptions to the * std::exception hierarchy. * Updated exceptions so that catch (...) is only done where necessary and * correct. * * ***************** Version 9 ***************** * User: Kirit Date: 19/03/02 Time: 20:54 * Updated in $/FOST/Cpp/FSCppUtil * Corrected history from last check-in. * Updated TestAX.IDL to remove registry entries from removed classes. * * ***************** Version 8 ***************** * User: Kirit Date: 19/03/02 Time: 19:48 * Updated in $/FOST/Cpp/FSCppUtil * Debug compiles now all end in '_d'. * The C++ implementation names (Type.cppName) have been changed to also * include the DLL that the implementation is in as per the documentation. * In all source files the following have been done: * * Ensured that every header file has a revision object. * * Ensured that every translation unit has a revision object. * * Ensured that every source file (which understands comments) * has a history section. * * Changed all copyright notices to be for Obsideon Ltd. * * Changed copyright notices to use the longest possible timeframe. * * ***************** Version 7 ***************** * User: Kirit Date: 20/02/02 Time: 0:43 * Updated in $/FOST/Cpp/FSCppUtil * Rebuilt destructors to stop any exception propagation. * * ***************** Version 6 ***************** * User: Kirit Date: 19/02/02 Time: 10:52 * Updated in $/FOST/Cpp/FSCppUtil * Altered interfaces to remove Boost pointers as they are not thread * safe. * * ***************** Version 5 ***************** * User: Kirit Date: 24/12/01 Time: 13:10 * Updated in $/FOST/Cpp/FSCppUtil * Stopped race condition when acquiring more than one Semaphore lock. * Allowed LockTimeout to return more detailed error information. * Allowed ExclusiveWrite to specify the number of possible read locks * that can be acquired. * * ***************** Version 4 ***************** * User: Kirit Date: 10/11/01 Time: 22:45 * Updated in $/FOST/Cpp/FSCppUtil * New (extended) Semaphore and ExclusiveWrite locking classes. * * ***************** Version 3 ***************** * User: Kirit Date: 4/11/01 Time: 3:36 * Updated in $/FOST/Cpp/FSCppUtil * Updates to support Mutex lock testing. * Header revision information now captured. * Periods<> container updated to better support error reporting and fault * finding. * * ***************** Version 2 ***************** * User: Kirit Date: 23/07/01 Time: 15:20 * Updated in $/FOST/FSCppUtil * Initial implementation of Mutex class (with attendant Lock class). * * ***************** Version 1 ***************** * User: Kirit Date: 20/07/01 Time: 15:49 * Created in $/FOST/FSCppUtil */