Sunteți pe pagina 1din 4

#ifndef __MUTEX_READERS_WRITERS #define __MUTEX_READERS_WRITERS class CMutexRW { protected: HANDLE m_semReaders; HANDLE m_semWriters; int m_nReaders; public: CMutexRW()

: m_semReaders(NULL), m_semWriters(NULL), m_nReaders(0) { // initialize the Readers & Writers variables m_semReaders = ::CreateSemaphore(NULL, 1, 1, NULL); m_semWriters = ::CreateSemaphore(NULL, 1, 1, NULL); m_nReaders = 0; if (m_semReaders == NULL || m_semWriters == NULL) { LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // De fault language (LPTSTR) &lpMsgBuf, 0, NULL ); TRACE( "***** ERROR: CreateSemaphore: %s\n", (LPCTSTR)lp MsgBuf ); LocalFree( lpMsgBuf ); } }; virtual ~CMutexRW() { if (m_semWriters) VERIFY( ::CloseHandle(m_semWriters) ); m_semWriters = NULL; if (m_semReaders) VERIFY( ::CloseHandle(m_semReaders) ); m_semReaders = NULL; } inline void Lock_DataRead(){ DWORD dwEvent = WAIT_TIMEOUT; // P( semReaders ) dwEvent = ::WaitForSingleObject( m_semReaders, INFINITE ); ASSERT(dwEvent == WAIT_OBJECT_0); m_nReaders++;

if (m_nReaders == 1) { // P( semWriters ) dwEvent = ::WaitForSingleObject( m_semWriters, INFINITE ); ASSERT(dwEvent == WAIT_OBJECT_0); } // V( semReaders ) VERIFY( ::ReleaseSemaphore( m_semReaders, 1, NULL ) ); }; inline void Unlock_DataRead(){ DWORD dwEvent = WAIT_TIMEOUT; // P( semReaders ) dwEvent = ::WaitForSingleObject( m_semReaders, INFINITE ); ASSERT(dwEvent == WAIT_OBJECT_0); m_nReaders--; if (m_nReaders == 0) { // V( semWriters ) VERIFY( ::ReleaseSemaphore(m_semWriters, 1, NULL) ); } // V( semReaders ) VERIFY( ::ReleaseSemaphore( m_semReaders, 1, NULL ) ); }; inline void Lock_DataWrite(){ DWORD dwEvent = WAIT_TIMEOUT; // P( semWriters ) dwEvent = ::WaitForSingleObject( m_semWriters, INFINITE ); ASSERT(dwEvent == WAIT_OBJECT_0); } inline void Unlock_DataWrite(){ // V( semWriters ) VERIFY( ::ReleaseSemaphore(m_semWriters, 1, NULL) ); }; }; class CReadLock { protected: CMutexRW* m_pMutexRW; bool m_bIsLocked; public: CReadLock(CMutexRW* pMutexRW, const bool bInitialLock = false) : m_pMutexRW(pMutexRW), m_bIsLocked(false) { ASSERT(m_pMutexRW); if (bInitialLock){ m_pMutexRW->Lock_DataRead(); m_bIsLocked = true; } };

inline const bool& IsLocked() const{ return m_bIsLocked; }; inline void Lock(){ ASSERT(m_bIsLocked == false); m_pMutexRW->Lock_DataRead(); m_bIsLocked = true; }; inline void Unlock(){ ASSERT(m_bIsLocked); m_pMutexRW->Unlock_DataRead(); m_bIsLocked = false; }; virtual ~CReadLock(){ if (m_bIsLocked){ m_pMutexRW->Unlock_DataRead(); } }; }; class CWriteLock { protected: CMutexRW* m_pMutexRW; bool m_bIsLocked; public: CWriteLock(CMutexRW* pMutexRW, const bool bInitialLock = false) : m_pMutexRW(pMutexRW), m_bIsLocked(false) { ASSERT(m_pMutexRW); if (bInitialLock){ m_pMutexRW->Lock_DataWrite(); m_bIsLocked = true; } }; inline const bool& IsLocked() const{ return m_bIsLocked; }; inline void Lock(){ ASSERT(m_bIsLocked == false); m_pMutexRW->Lock_DataWrite(); m_bIsLocked = true; }; inline void Unlock(){ ASSERT(m_bIsLocked); m_pMutexRW->Unlock_DataWrite(); m_bIsLocked = false; }; virtual ~CWriteLock(){ if (m_bIsLocked){ m_pMutexRW->Unlock_DataWrite(); } }; };

#endif // end #ifndef __MUTEX_READERS_WRITERS

S-ar putea să vă placă și