Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

183 lines
4.6 KiB

#ifndef _CEXRWLCK_H
#define _CEXRWLCK_H
#include <limits.h>
#ifndef WIN16
//
// This class contains the meat - does actual locking etc...
//
class CExShareLock {
private :
long cReadLock ; // Number of Readers who have passed through the lock OR
// the number of readers waiting for the lock (will be negative).
// A value of 0 means nobody in the lock
long cOutRdrs ; // The number of readers remainin in the lock if
// there is a writer waiting. This can become temporarily negative
CRITICAL_SECTION critWriters ; // Critical section to allow only one writer into the lock at a time
HANDLE hWaitingWriters ; // Semaphore for waiting writers to block on (Only 1 ever, others will
// be queued on critWriters)
HANDLE hWaitingReaders ; // Semaphore for waiting readers to block on
public :
CExShareLock( ) ;
~CExShareLock( ) ;
void ShareLock( ) ;
void ShareUnlock( ) ;
void ExclusiveLock( ) ;
void ExclusiveUnlock( ) ;
BOOL SharedToExclusive( ) ; // returns TRUE if successful
} ;
//
// This class implements a wrapper class around CExShareLock class so that
// it alows the nested hold on Exclusive lock if a thread
// has an exclusive lock and calls for holding exclusive lock or Share lock
// again
//
class CExShareLockWithNestAllowed
{
private :
CExShareLock m_lock; // class around which the wrapper is formed
DWORD m_dwThreadID; // The thread id of the thred currently holding
// the exclusive lock
DWORD m_dwNestCount; // The count of number of nested calls to lock by the thread holding the
// exclusive lock less 1
public :
CExShareLockWithNestAllowed( ) : m_dwThreadID(0xffffffff), m_dwNestCount(0)
{
// nothing
};
~CExShareLockWithNestAllowed( )
{
Assert( (m_dwThreadID == 0xffffffff ) && ( m_dwNestCount == 0 ) );
}
void ShareLock( )
{
if(! nest() )
{
m_lock.ShareLock();
}
}
void ShareUnlock( )
{
if (! unnest() )
{
m_lock.ShareUnlock();
}
}
void ExclusiveLock( )
{
if(! nest() )
{
m_lock.ExclusiveLock();
Assert( m_dwNestCount == 0 );
Assert( m_dwThreadID == 0xffffffff );
m_dwThreadID = GetCurrentThreadId();
}
}
void ExclusiveUnlock( )
{
if (! unnest() )
{
m_dwThreadID = 0xffffffff;
m_lock.ExclusiveUnlock();
}
}
protected :
BOOL nest()
{
if( m_dwThreadID != GetCurrentThreadId() )
return ( FALSE );
m_dwNestCount++;
return( TRUE );
}
BOOL unnest()
{
if ( ! m_dwNestCount )
return ( FALSE );
Assert( m_dwThreadID == GetCurrentThreadId() );
m_dwNestCount--;
return( TRUE);
}
};
#else
class CExShareLock {
public:
CExShareLock() {
InitializeCriticalSection(&m_cs);
};
~CExShareLock() {
DeleteCriticalSection(&m_cs);
};
void ShareLock(){
EnterCriticalSection(&m_cs);
};
void ShareUnlock() {
LeaveCriticalSection(&m_cs);
};
void ExclusiveLock(){
EnterCriticalSection(&m_cs);
};
void ExclusiveUnlock() {
LeaveCriticalSection(&m_cs);
};
BOOL SharedToExclusive() {
return (TRUE);
};
private:
CRITICAL_SECTION m_cs;
};
class CExShareLockWithNestAllowed {
public:
CExShareLockWithNestAllowed() {
InitializeCriticalSection(&m_cs);
};
~CExShareLockWithNestAllowed() {
DeleteCriticalSection(&m_cs);
};
void ShareLock(){
EnterCriticalSection(&m_cs);
};
void ShareUnlock() {
LeaveCriticalSection(&m_cs);
};
void ExclusiveLock(){
EnterCriticalSection(&m_cs);
};
void ExclusiveUnlock() {
LeaveCriticalSection(&m_cs);
};
private:
CRITICAL_SECTION m_cs;
};
#endif
#endif