// destructor... CMclAutoLock::~CMclAutoLock(void) { BOOL bStatus = TRUE; if (m_hMutexHandle) { bStatus = ::ReleaseMutex(m_hMutexHandle); } else if (m_pcMutex) { bStatus = m_pcMutex->Release(); } else if (m_pCritSec) { ::LeaveCriticalSection(m_pCritSec); } else { m_pcCritSec->Leave(); } if (!bStatus) { CMclThrowError( ::GetLastError()); } }
CMclMailbox::CMclMailbox( DWORD dwMaxDepth, DWORD cbMsgSize, LPCTSTR lpszName, LPSECURITY_ATTRIBUTES lpMailboxAttributes) : m_cSharedMemory( dwMaxDepth * cbMsgSize + sizeof(MailboxHdr), lpszName, lpMailboxAttributes), m_pHdr(NULL), m_pBase(NULL), m_cGuardMutexAPtr(NULL), m_cFreeCountSemaphoreAPtr(NULL), m_cPendingCountSemaphoreAPtr(NULL), m_dwStatus(NO_ERROR), m_bIsCreator(FALSE) { // temporary buffer for our names... TCHAR szName[MAX_PATH]; // check the status of the shared memory object in case // exceptions are disabled... CMCL_CHECK_CREATION_STATUS(m_cSharedMemory.Status(), m_dwStatus); // create the name for the guard mutex... CreateGuardMutexName( szName, lpszName); // create the guard mutex... // check for errors in case exceptions are disabled... m_cGuardMutexAPtr = new CMclMutex( TRUE, szName, lpMailboxAttributes); CMCL_CHECK_AUTOPTR_OBJECT(m_cGuardMutexAPtr, m_dwStatus); CMCL_CHECK_CREATION_STATUS(m_cGuardMutexAPtr->Status(), m_dwStatus); // check if we are the creator of the guard mutex... if (m_cGuardMutexAPtr->Status() == ERROR_ALREADY_EXISTS) { // in this case we don't own the mutex because we did not // create it so we need to wait for it to prevent race conditions // with other objects created at about the same time, // this ensure that the creating object always finishes its // constructor first... m_cGuardMutexAPtr->Wait(INFINITE); m_bIsCreator = FALSE; } else { // we own the mutex now... m_bIsCreator = TRUE; } // create the name for the free count semaphore... CreateFreeCountSemaphoreName( szName, lpszName); // create the free count semaphore... // check for errors in case exceptions are disabled... m_cFreeCountSemaphoreAPtr = new CMclSemaphore( dwMaxDepth, dwMaxDepth, szName, lpMailboxAttributes); CMCL_CHECK_AUTOPTR_OBJECT(m_cFreeCountSemaphoreAPtr, m_dwStatus); CMCL_CHECK_CREATION_STATUS(m_cFreeCountSemaphoreAPtr->Status(), m_dwStatus); // create the name for the pending count semaphore... CreatePendingCountSemaphoreName( szName, lpszName); // create the pending count semaphore... // check for errors in case exceptions are disabled... m_cPendingCountSemaphoreAPtr = new CMclSemaphore( 0, dwMaxDepth, szName, lpMailboxAttributes); CMCL_CHECK_AUTOPTR_OBJECT(m_cPendingCountSemaphoreAPtr, m_dwStatus); CMCL_CHECK_CREATION_STATUS(m_cPendingCountSemaphoreAPtr->Status(), m_dwStatus); // store pointer to beginning of shared memory... m_pHdr = (MailboxHdr *) m_cSharedMemory.GetPtr(); // store pointer to base of mailbox slots... m_pBase = (void *) ((BYTE *) m_pHdr + sizeof(MailboxHdr)); // initialize the mailbox slots if we are the creator of the shared memory... // if we are the creator of the shared memory, we are the creator of the // guard mutex and we initially own it... if (m_bIsCreator) { m_pHdr->dwMaxDepth = dwMaxDepth; m_pHdr->cbMsgSize = cbMsgSize; m_pHdr->dwBaseOffset = sizeof(MailboxHdr); m_pHdr->dwHeadIndex = 0; m_pHdr->dwTailIndex = 0; } // we need to release the guard mutex whether or not // we are the creator... m_cGuardMutexAPtr->Release(); if (!m_bIsCreator) { // it is an error for a second object to try to open the // mailbox with different message buffer parameters, so check for this condition... if ((m_pHdr->dwMaxDepth != dwMaxDepth) || (m_pHdr->cbMsgSize != cbMsgSize)) { m_dwStatus = ERROR_INVALID_PARAMETER; CMclThrowError(m_dwStatus); return; } } }