// 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());
    }
}
Example #2
0
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;
        }
    }
}