?? wrsync.cpp
字號:
#include "wrSync.h"
wrSync::wrSync()
{
// Initially no readers want access, no writers want access, and
// no threads are accessing the resource
m_nWaitingReaders = m_nWaitingWriters = m_nActive = 0;
KeInitializeSemaphore(&m_hsemReaders,0,MAXLONG);
KeInitializeSemaphore(&m_hsemWriters,0,MAXLONG);
KeInitializeSpinLock(&m_SpinLock);
}
wrSync::~wrSync()
{
m_nWaitingReaders = m_nWaitingWriters = m_nActive = 0;
}
void wrSync::WaitToRead()
{
// Ensure exclusive access to the member variables
KIRQL irql;
KeAcquireSpinLock(&m_SpinLock,&irql);
// Are there writers waiting or is a writer writing?
bool fResourceWritePending = (m_nWaitingWriters || (m_nActive < 0));
if (fResourceWritePending)
{
// This reader must wait, increment the count of waiting readers
m_nWaitingReaders++;
}
else
{
// This reader can read, increment the count of active readers
m_nActive++;
}
// Allow other threads to attempt reading/writing
KeReleaseSpinLock(&m_SpinLock,irql);
if (fResourceWritePending)
{
// This thread must wait
KeWaitForSingleObject(&m_hsemReaders,Executive,KernelMode,FALSE, NULL);
}
}
void wrSync::WaitToWrite()
{
// Ensure exclusive access to the member variables
KIRQL irql;
KeAcquireSpinLock(&m_SpinLock,&irql);
// Are there any threads accessing the resource?
bool fResourceOwned = (m_nActive != 0);
if (fResourceOwned)
{
// This writer must wait, increment the count of waiting writers
m_nWaitingWriters++;
}
else
{
// This writer can write, decrement the count of active writers
m_nActive = -1;
}
// Allow other threads to attempt reading/writing
KeReleaseSpinLock(&m_SpinLock,irql);
if (fResourceOwned)
{
// This thread must wait
KeWaitForSingleObject(&m_hsemWriters,Executive,KernelMode,FALSE, NULL);
}
}
void wrSync::Done()
{
// Ensure exclusive access to the member variables
KIRQL irql;
KeAcquireSpinLock(&m_SpinLock,&irql);
if (m_nActive > 0)
{
// Readers have control so a reader must be done
m_nActive--;
}
else
{
// Writers have control so a writer must be done
m_nActive++;
}
PKSEMAPHORE hsem = NULL; // Assume no threads are waiting
LONG lCount = 1; // Assume only 1 waiter wakes; always true for writers
if (m_nActive == 0)
{
// No thread has access, who should wake up?
// NOTE: It is possible that readers could never get access
// if there are always writers wanting to write
if (m_nWaitingWriters > 0)
{
// Writers are waiting and they take priority over readers
m_nActive = -1; // A writer will get access
m_nWaitingWriters--; // One less writer will be waiting
hsem = &m_hsemWriters; // Writers wait on this semaphore
// NOTE: The semaphore will release only 1 writer thread
}
else if (m_nWaitingReaders > 0)
{
// Readers are waiting and no writers are waiting
m_nActive = m_nWaitingReaders; // All readers will get access
m_nWaitingReaders = 0; // No readers will be waiting
hsem = &m_hsemReaders; // Readers wait on this semaphore
lCount = m_nActive; // Semaphore releases all readers
}
else
{
// There are no threads waiting at all; no semaphore gets released
}
}
// Allow other threads to attempt reading/writing
KeReleaseSpinLock(&m_SpinLock,irql);
if (hsem != NULL)
{
// Some threads are to be released
KeReleaseSemaphore(hsem,NULL,lCount,TRUE);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -