// this struct encapsulates the lock request
struct LockRequest
{
enum LockType_En { READ_LOCK, WRITE_LOCK };
LockRequest(RWLock* pRWLock, LockType_En lockType) :
m_pRWLock(pRWLock), m_lockType(lockType) {};
RWLock* m_pRWLock;
LockType_En m_lockType;
};
static void RWLock::MultipleRWLock(LockRequest* pRequest, int nCount)
{
HANDLE dataHandles[MAXIMUM_WAIT_OBJECTS];
HANDLE readersHandles[MAXIMUM_WAIT_OBJECTS];
RWLock* readers[MAXIMUM_WAIT_OBJECTS];
int nDataHandles = 0, nReadersHandles= 0;
// Build handles array
for (int i = 0; i < nCount; i++)
{
if (pRequest[i].m_lockType == LockRequest::WRITE_LOCK)
dataHandles[nDataHandles++] =
pRequest[i].m_pRWLock->m_hDataEvent;
else
{
readersHandles[nReadersHandles] =
pRequest[i].m_pRWLock->m_hReadersEvent;
readers[nReadersHandles++] = pRequest[i].m_pRWLock;
}
}
// lock all m_nReaders, check them, and if equal zero,
// add to dataHandles
WaitForMultipleObjects(nReadersHandles, readersHandles, TRUE,
INFINITE);
for (i = 0; i < nReadersHandles; i++)
{
if (readers[i]->m_pRWLock.m_nReaders++ == 0)
dataHandles[nDataHandles++] =
readers[i]->m_pRWLock.m_hDataEvent;
}
// Perform the locks on the data
WaitForMultipleObjects(nDataHandles, dataHandles, TRUE, INFINITE);
// release locks on m_nReaders
for (i = 0; i < nReadersHandles; i++)
SetEvent(readers[i]->m_pRWLock.m_hReadersEvent);
}
End of Listing