ultimatepp/uppdev/RwLock/RwLock3.hpp
cxl 4a1c627474 Adding uppdev....
git-svn-id: svn://ultimatepp.org/upp/trunk@328 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2008-08-15 08:36:24 +00:00

64 lines
1.8 KiB
C++

class RwLock
{
RwLock ( RwLock const& );
RwLock const& operator = ( RwLock const& );
private:
LONG m_count;
LONG m_rdwake;
HANDLE m_wrwset;
HANDLE m_rdwset;
CRITICAL_SECTION m_wrlock;
public:
RwLock()
: m_count ( LONG_MAX ),
m_rdwake ( 0 ),
m_wrwset ( CreateEvent ( 0, FALSE, FALSE, 0 ) ),
m_rdwset ( CreateSemaphore ( 0, 0, LONG_MAX, 0 ) )
{
InitializeCriticalSection ( &m_wrlock );
}
~RwLock() throw()
{
DeleteCriticalSection ( &m_wrlock );
CloseHandle ( m_rdwset );
CloseHandle ( m_wrwset );
}
public:
void EnterWrite() {
EnterCriticalSection ( &m_wrlock );
LONG count = InterlockedExchangeAdd(&m_count, -LONG_MAX);
if(count < LONG_MAX)
if(InterlockedExchangeAdd ( &m_rdwake, LONG_MAX - count ) + LONG_MAX - count )
WaitForSingleObject ( m_wrwset, INFINITE );
}
void LeaveWrite() {
LONG count = InterlockedExchangeAdd ( &m_count, LONG_MAX );
if (count < 0)
ReleaseSemaphore ( m_rdwset, count * -1, 0 );
LeaveCriticalSection ( &m_wrlock );
}
public:
void EnterRead() {
LONG count = InterlockedDecrement ( &m_count );
if(count < 0)
WaitForSingleObject ( m_rdwset, INFINITE );
}
void LeaveRead() {
LONG count = InterlockedIncrement ( &m_count );
if ( count < 1 ) {
if ( ! InterlockedDecrement ( &m_rdwake ) )
SetEvent ( m_wrwset );
}
}
};