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 ); } } };