Listing 1: Incorrect MultipleRWLock

// 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 —