📄 utsem.h
字号:
/* ----------------------------------------------------------------------------
@mfunc
SYNCHRO class - Constructor
Create the event, initialize the critical section objects and reader count,
and return.
---------------------------------------------------------------------------- */
inline UTSemCheapReadWrite::UTSemCheapReadWrite(void)
{
// Create the manual-reset event (the only init that can fail)
hevReadDone = CreateEvent(NULL, TRUE, TRUE, NULL);
hevReaderPresent = CreateEvent(NULL, TRUE, FALSE, NULL);
hevWriterPresent = CreateEvent(NULL, TRUE, FALSE, NULL);
fInitSucceeded = (hevReadDone != NULL) &&
(hevReaderPresent != NULL) &&
(hevWriterPresent != NULL);
// If we created the event, proceed with the risk-free initialization
if (fInitSucceeded)
{
cReaders = -1;
cWriters = -1;
m_fReader = FALSE;
InitializeCriticalSection(&csExclusive);
InitializeCriticalSection(&csReader);
InitializeCriticalSection(&csWriter);
}
return;
}
/* ----------------------------------------------------------------------------
@mfunc
SYNCHRO class - Destructor
Free the event, delete the critical section objects, and return.
---------------------------------------------------------------------------- */
inline UTSemCheapReadWrite::~UTSemCheapReadWrite(void)
{
if (IsValid())
{
CloseHandle(hevReadDone);
DeleteCriticalSection(&csExclusive);
DeleteCriticalSection(&csReader);
}
return;
}
/* ----------------------------------------------------------------------------
@mfunc
SYNCHRO class - Lock member function
---------------------------------------------------------------------------- */
inline BOOL UTSemCheapReadWrite::Lock(SYNCH_LOCK_TYPE lt)
{
// Verify that the object is valid
if (! IsValid())
return FALSE;
// Verify that the specified lock type is supported by this implementation
if (lt == SLT_READPROMOTE)
return FALSE;
// Claim the read lock or write lock as specified
if (lt == SLT_READ)
{
// First try to get the reader lock cheaply by incrementing
// the reader count. Only if reader count is positive
// do we try and test that a reader is present
if (InterlockedIncrement (&cReaders) > 0)
{
// Test that there is actually a reader holding on the the lock.
// It is possible to that the reader count is greater that -1
// but still there are no readers who have actually acquired the
// lock
if (WaitForSingleObject (hevReaderPresent, 0) == WAIT_OBJECT_0)
{
// Only if there are no writers waiting to acquire the lock
// do we try to acquire the lock. Without this we cannot
// guarantee that the writer wont starve.
if (WaitForSingleObject (hevWriterPresent, 0) == WAIT_TIMEOUT)
return TRUE;
}
}
// Decrement extra reader count
InterlockedDecrement (&cReaders);
// Claim the <csExclusive> critical section. This call blocks if there's
// an active writer or if there's a writer waiting for active readers to
// complete.
EnterCriticalSection(&csExclusive);
// Claim access to the reader count. If this blocks, it's only for the
// briefest moment, while other threads go through to increment or
// decrement the reader count.
EnterCriticalSection(&csReader);
// Increment the reader count. If this is the first reader, we reset the
// hevReadDone event so that the next writer blocks.
if (InterlockedIncrement (&cReaders) >= 0)
{
if (!m_fReader)
{
SetEvent (hevReaderPresent);
ResetEvent(hevReadDone);
m_fReader = TRUE;
}
}
// Release access to the reader count
LeaveCriticalSection(&csReader);
// Release access to the <csExclusive> critical section. This enables
// other readers to come through and the next writer to wait for active
// readers to complete (which in turn prevents new readers from entering).
LeaveCriticalSection(&csExclusive);
}
else
{
// Verify that since this isn't the read lock, that it's the write lock
Assert(lt == SLT_WRITE);
// Gain access to the writer count
EnterCriticalSection(&csWriter);
// Increment the writer count. If this is the writer reader, we set the
// hevWriterPresent event so that new readers give way to the writer.
if (InterlockedIncrement (&cWriters) == 0)
{
SetEvent (hevWriterPresent);
}
// Release access to the writer count
LeaveCriticalSection(&csWriter);
// Claim the <csExclusive> critical section. This not only prevents other
// threads from claiming the write lock, but also prevents any new threads
// from claiming the read lock.
EnterCriticalSection(&csExclusive);
// Wait for the active readers to release their read locks.
return WaitForSingleObject(hevReadDone, INFINITE) == WAIT_OBJECT_0;
}
return TRUE;
} //End Lock
/* ----------------------------------------------------------------------------
@mfunc
SYNCHRO class - Unlock member function
---------------------------------------------------------------------------- */
inline BOOL UTSemCheapReadWrite::UnLock(SYNCH_LOCK_TYPE lt)
{
// Verify that the object is valid
if (! IsValid())
return FALSE;
// Verify that the specified lock type is supported by this implementation
if (lt == SLT_READPROMOTE)
return FALSE;
// Release the read lock or write lock as specified
if (lt == SLT_READ)
{
// Claim access to the reader count. If this blocks, it's only for the
// briefest moment, while other threads go through to increment or
// decrement the reader count.
EnterCriticalSection(&csReader);
// Decrement the reader count. If this is the last reader, set
// <hevReadDone>, which allows the first waiting writer to proceed.
if (InterlockedDecrement (&cReaders) < 0)
{
ResetEvent (hevReaderPresent);
SetEvent(hevReadDone);
m_fReader = FALSE;
}
// Release access to the reader count
LeaveCriticalSection(&csReader);
}
else
{
// Verify that since this isn't the read lock, that it's the write lock
Assert(lt == SLT_WRITE);
// Gain access to the writer count
EnterCriticalSection(&csWriter);
// Decrement the writer count. If this is the last writer, we reset the
// hevWriterPresent event.
if (InterlockedDecrement (&cWriters) < 0)
{
ResetEvent (hevWriterPresent);
}
// Release access to the writer count
LeaveCriticalSection(&csWriter);
// Make <csExclusive> available to one other writer or to the first reader
LeaveCriticalSection(&csExclusive);
}
return TRUE;
} //End Unlock
/* ----------------------------------------------------------------------------
@class CSemExclusive:
@rev 0 | 4th Feb,95 | GaganC | Created
---------------------------------------------------------------------------- */
class CSemExclusive
{
public:
CSemExclusive (void);
~CSemExclusive (void);
void Lock (void);
void UnLock (void);
private:
CRITICAL_SECTION m_csx;
}; //end class CSemExclusive
//-----------------------------------------------------------------------------
//
// IMPLEMENTATION of class CSemExclusive
//
//-----------------------------------------------------------------------------
/* ----------------------------------------------------------------------------
@mfunc
---------------------------------------------------------------------------- */
inline CSemExclusive::CSemExclusive
(
void
)
{
InitializeCriticalSection (&m_csx);
}
/* ----------------------------------------------------------------------------
@mfunc
---------------------------------------------------------------------------- */
inline CSemExclusive::~CSemExclusive
(
void
)
{
DeleteCriticalSection (&m_csx);
}
/* ----------------------------------------------------------------------------
@mfunc
---------------------------------------------------------------------------- */
inline void CSemExclusive::Lock
(
void
)
{
EnterCriticalSection (&m_csx);
}
/* ----------------------------------------------------------------------------
@mfunc
---------------------------------------------------------------------------- */
inline void CSemExclusive::UnLock
(
void
)
{
LeaveCriticalSection (&m_csx);
}
/* ----------------------------------------------------------------------------
@class CSemExclusiveSL:
---------------------------------------------------------------------------- */
class CSemExclusiveSL
{
public:
CSemExclusiveSL (void);
~CSemExclusiveSL (void);
void Lock (void);
void UnLock (void);
private:
DWORD volatile m_dwLock;
DWORD volatile *m_pdwLock;
DWORD volatile m_dwOwningThread;
ULONG volatile m_ulRecursionCount;
};
/* ----------------------------------------------------------------------------
@mfunc
---------------------------------------------------------------------------- */
inline CSemExclusiveSL::CSemExclusiveSL ( void )
{
m_dwOwningThread = 0;
m_ulRecursionCount = 0;
m_dwLock = 0;
m_pdwLock = &m_dwLock;
}
/* ----------------------------------------------------------------------------
@mfunc
---------------------------------------------------------------------------- */
inline CSemExclusiveSL::~CSemExclusiveSL ( void )
{
//Nothing to do
}
/* ----------------------------------------------------------------------------
@mfunc
** Lock -- Obtains an SMP safe lock on the address given.
** WARNING: Does not release any semaphore or critsec when waiting.
**
@rev 0 Created 04/20/93 by LaleD
@rev 1 modified 7/13/96 by shaiwals
---------------------------------------------------------------------------- */
inline void CSemExclusiveSL::Lock ( void )
{
DWORD i;
DWORD n = 0;
int m = 0;
startover:
if (InterlockedExchange((long *)m_pdwLock, 1) == 0)
{
m_dwOwningThread = GetCurrentThreadId();
return;
}
if (m_dwOwningThread == GetCurrentThreadId())
{
m_ulRecursionCount++;
return;
}
// Give away my time slice to another thread as the probability
// of my getting this lock right away are low - shaiwals
//Sleep (1);
/* retry using safe test only after cheaper, unsafe test succeeds */
for (i = 0 ; i < (DWORD)(10000) ; i++)
{
if (*m_pdwLock == 0)
{
goto startover;
}
}
/*
** Yield after hitting the cspinctr limit
** Sleep(0) only yields to threads of same priority
** if hit limit 10000 times, sleep 5sec and test for kill
** this provides a chance to CTRL-C it if stuck in loop
*/
m++;
if( ( m % 10000 ) == 0)
{
Sleep(5000);
}
else
{
Sleep(0);
}
goto startover;
/* try again */
}
/* ----------------------------------------------------------------------------
@mfunc
---------------------------------------------------------------------------- */
inline void CSemExclusiveSL::UnLock ( void )
{
AssertSz (m_dwOwningThread == GetCurrentThreadId(), \
"Lock released by someone who doesnt own the lock!!!");
if (m_ulRecursionCount > 0)
{
m_ulRecursionCount--;
return;
}
m_dwOwningThread = 0;
*m_pdwLock = 0;
}
#endif __UTSEM_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -