Esempio n. 1
0
PAL_ERROR
CorUnix::InternalReleaseSemaphore(
    CPalThread *pthr,
    HANDLE hSemaphore,
    LONG lReleaseCount,
    LPLONG lpPreviousCount
    )
{
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pobjSemaphore = NULL;
    ISynchStateController *pssc = NULL;
    SemaphoreImmutableData *pSemaphoreData;
    LONG lOldCount;

    _ASSERTE(NULL != pthr);

    ENTRY("InternalReleaseSempahore(pthr=%p, hSemaphore=%p, lReleaseCount=%d, "
        "lpPreviousCount=%p)\n",
        pthr,
        hSemaphore,
        lReleaseCount,
        lpPreviousCount
        );

    if (0 >= lReleaseCount)
    {
        palError = ERROR_INVALID_PARAMETER;
        goto InternalReleaseSemaphoreExit;
    }

    palError = g_pObjectManager->ReferenceObjectByHandle(
        pthr,
        hSemaphore,
        &aotSempahore, 
        0, // Should be SEMAPHORE_MODIFY_STATE; currently ignored (no Win32 security)
        &pobjSemaphore
        );

    if (NO_ERROR != palError)
    {
        ERROR("Unable to obtain object for handle %p (error %d)!\n", hSemaphore, palError);
        goto InternalReleaseSemaphoreExit;
    }

    palError = pobjSemaphore->GetImmutableData(reinterpret_cast<void**>(&pSemaphoreData));
    
    if (NO_ERROR != palError)
    {
        ASSERT("Error %d obtaining object data\n", palError);
        goto InternalReleaseSemaphoreExit;
    }

    palError = pobjSemaphore->GetSynchStateController(
        pthr,
        &pssc
        );

    if (NO_ERROR != palError)
    {
        ASSERT("Error %d obtaining synch state controller\n", palError);
        goto InternalReleaseSemaphoreExit;
    }

    palError = pssc->GetSignalCount(&lOldCount);

    if (NO_ERROR != palError)
    {
        ASSERT("Error %d obtaining current signal count\n", palError);
        goto InternalReleaseSemaphoreExit;
    }

    _ASSERTE(lOldCount <= pSemaphoreData->lMaximumCount);
    if (lReleaseCount > pSemaphoreData->lMaximumCount - lOldCount)
    {
        palError = ERROR_INVALID_PARAMETER;
        goto InternalReleaseSemaphoreExit;
    }

    palError = pssc->IncrementSignalCount(lReleaseCount);
    
    if (NO_ERROR != palError)
    {
        ASSERT("Error %d incrementing signal count\n", palError);
        goto InternalReleaseSemaphoreExit;
    }

    if (NULL != lpPreviousCount)
    {
        *lpPreviousCount = lOldCount;
    }

InternalReleaseSemaphoreExit:

    if (NULL != pssc)
    {
        pssc->ReleaseController();
    }

    if (NULL != pobjSemaphore)
    {
        pobjSemaphore->ReleaseReference(pthr);
    }

    LOGEXIT("InternalReleaseSemaphore returns %d\n", palError);

    return palError;
}
Esempio n. 2
0
PAL_ERROR
CorUnix::InternalCreateSemaphore(
    CPalThread *pthr,
    LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
    LONG lInitialCount,
    LONG lMaximumCount,
    LPCWSTR lpName,
    HANDLE *phSemaphore
    )
{
    CObjectAttributes oa(lpName, lpSemaphoreAttributes);
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pobjSemaphore = NULL;
    IPalObject *pobjRegisteredSemaphore = NULL;
    SemaphoreImmutableData *pSemaphoreData;

    _ASSERTE(NULL != pthr);
    _ASSERTE(NULL != phSemaphore);

    ENTRY("InternalCreateSemaphore(pthr=%p, lpSemaphoreAttributes=%p, "
        "lInitialCount=%d, lMaximumCount=%d, lpName=%p, phSemaphore=%p)\n",
        pthr,
        lpSemaphoreAttributes,
        lInitialCount,
        lMaximumCount,
        lpName,
        phSemaphore
        );

    if (lpName != nullptr)
    {
        ASSERT("lpName: Cross-process named objects are not supported in PAL");
        palError = ERROR_NOT_SUPPORTED;
        goto InternalCreateSemaphoreExit;
    }

    if (lMaximumCount <= 0)
    {
        ERROR("lMaximumCount is invalid (%d)\n", lMaximumCount);
        palError = ERROR_INVALID_PARAMETER;
        goto InternalCreateSemaphoreExit;
    }

    if ((lInitialCount < 0) || (lInitialCount > lMaximumCount))
    {
        ERROR("lInitialCount is invalid (%d)\n", lInitialCount);
        palError = ERROR_INVALID_PARAMETER;
        goto InternalCreateSemaphoreExit;
    }

    palError = g_pObjectManager->AllocateObject(
        pthr,
        &otSemaphore,
        &oa,
        &pobjSemaphore
        );

    if (NO_ERROR != palError)
    {
        goto InternalCreateSemaphoreExit;
    }

    palError = pobjSemaphore->GetImmutableData(reinterpret_cast<void**>(&pSemaphoreData));

    if (NO_ERROR != palError)
    {
        ASSERT("Error %d obtaining object data\n", palError);
        goto InternalCreateSemaphoreExit;
    }

    pSemaphoreData->lMaximumCount = lMaximumCount;

    if (0 != lInitialCount)
    {
        ISynchStateController *pssc;

        palError = pobjSemaphore->GetSynchStateController(
            pthr,
            &pssc
            );

        if (NO_ERROR == palError)
        {
            palError = pssc->SetSignalCount(lInitialCount);
            pssc->ReleaseController();
        }

        if (NO_ERROR != palError)
        {
            ASSERT("Unable to set new semaphore state (%d)\n", palError);
            goto InternalCreateSemaphoreExit;
        }
    }

    palError = g_pObjectManager->RegisterObject(
        pthr,
        pobjSemaphore,
        &aotSempahore, 
        0, // Should be SEMAPHORE_ALL_ACCESS; currently ignored (no Win32 security)
        phSemaphore,
        &pobjRegisteredSemaphore
        );

    //
    // pobjSemaphore is invalidated by the call to RegisterObject, so NULL it
    // out here to ensure that we don't try to release a reference on
    // it down the line.
    //
    
    pobjSemaphore = NULL;

InternalCreateSemaphoreExit:

    if (NULL != pobjSemaphore)
    {
        pobjSemaphore->ReleaseReference(pthr);
    }

    if (NULL != pobjRegisteredSemaphore)
    {
        pobjRegisteredSemaphore->ReleaseReference(pthr);
    }

    LOGEXIT("InternalCreateSemaphore returns %d\n", palError);

    return palError;
}
Esempio n. 3
0
PAL_ERROR
CorUnix::InternalReleaseMutex(
    CPalThread *pthr,
    HANDLE hMutex
    )
{
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pobjMutex = NULL;
    ISynchStateController *pssc = NULL;
    PalObjectTypeId objectTypeId;

    _ASSERTE(NULL != pthr);

    ENTRY("InternalReleaseMutex(pthr=%p, hMutex=%p)\n",
        pthr,
        hMutex
        );

    palError = g_pObjectManager->ReferenceObjectByHandle(
        pthr,
        hMutex,
        &aotAnyMutex,
        0, // should be MUTEX_MODIFY_STATE -- current ignored (no Win32 security)
        &pobjMutex
        );

    if (NO_ERROR != palError)
    {
        ERROR("Unable to obtain object for handle %p (error %d)!\n", hMutex, palError);
        goto InternalReleaseMutexExit;
    }

    objectTypeId = pobjMutex->GetObjectType()->GetId();
    if (objectTypeId == otiMutex)
    {
        palError = pobjMutex->GetSynchStateController(
            pthr,
            &pssc
            );

        if (NO_ERROR != palError)
        {
            ASSERT("Error %d obtaining synch state controller\n", palError);
            goto InternalReleaseMutexExit;
        }

        palError = pssc->DecrementOwnershipCount();

        if (NO_ERROR != palError)
        {
            ERROR("Error %d decrementing mutex ownership count\n", palError);
            goto InternalReleaseMutexExit;
        }
    }
    else
    {
        _ASSERTE(objectTypeId == otiNamedMutex);

        SharedMemoryProcessDataHeader *processDataHeader =
            SharedMemoryProcessDataHeader::PalObject_GetProcessDataHeader(pobjMutex);
        _ASSERTE(processDataHeader != nullptr);
        try
        {
            static_cast<NamedMutexProcessData *>(processDataHeader->GetData())->ReleaseLock();
        }
        catch (SharedMemoryException ex)
        {
            palError = ex.GetErrorCode();
            goto InternalReleaseMutexExit;
        }
    }

InternalReleaseMutexExit:

    if (NULL != pssc)
    {
        pssc->ReleaseController();
    }

    if (NULL != pobjMutex)
    {
        pobjMutex->ReleaseReference(pthr);
    }

    LOGEXIT("InternalReleaseMutex returns %i\n", palError);

    return palError;
}
Esempio n. 4
0
PAL_ERROR
CorUnix::InternalCreateMutex(
    CPalThread *pthr,
    LPSECURITY_ATTRIBUTES lpMutexAttributes,
    BOOL bInitialOwner,
    LPCSTR lpName,
    HANDLE *phMutex
    )
{
    CObjectAttributes oa(nullptr, lpMutexAttributes);
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pobjMutex = NULL;
    IPalObject *pobjRegisteredMutex = NULL;
    ISynchStateController *pssc = NULL;
    HANDLE hMutex = nullptr;

    _ASSERTE(NULL != pthr);
    _ASSERTE(NULL != phMutex);

    ENTRY("InternalCreateMutex(pthr=%p, lpMutexAttributes=%p, bInitialOwner=%d"
        ", lpName=%p, phMutex=%p)\n",
        pthr,
        lpMutexAttributes,
        bInitialOwner,
        lpName,
        phMutex
        );

    if (lpName != nullptr && lpName[0] == '\0')
    {
        // Empty name is treated as a request for an unnamed process-local mutex
        lpName = nullptr;
    }

    CObjectType *ot = lpName == nullptr ? &otMutex : &otNamedMutex;
    CAllowedObjectTypes *aot = lpName == nullptr ? &aotMutex : &aotNamedMutex;

    palError = g_pObjectManager->AllocateObject(
        pthr,
        ot,
        &oa,
        &pobjMutex
        );

    if (NO_ERROR != palError)
    {
        goto InternalCreateMutexExit;
    }

    if (lpName == nullptr)
    {
        palError = pobjMutex->GetSynchStateController(
            pthr,
            &pssc
            );

        if (NO_ERROR != palError)
        {
            ASSERT("Unable to create state controller (%d)\n", palError);
            goto InternalCreateMutexExit;
        }

        if (bInitialOwner)
        {
            palError = pssc->SetOwner(pthr);
        }
        else
        {
            palError = pssc->SetSignalCount(1);
        }

        pssc->ReleaseController();

        if (NO_ERROR != palError)
        {
            ASSERT("Unable to set initial mutex state (%d)\n", palError);
            goto InternalCreateMutexExit;
        }
    }

    palError = g_pObjectManager->RegisterObject(
        pthr,
        pobjMutex,
        aot,
        0, // should be MUTEX_ALL_ACCESS -- currently ignored (no Win32 security)
        &hMutex,
        &pobjRegisteredMutex
        );

    if (palError != NO_ERROR)
    {
        _ASSERTE(palError != ERROR_ALREADY_EXISTS); // PAL's naming infrastructure is not used for named mutexes
        _ASSERTE(pobjRegisteredMutex == nullptr);
        _ASSERTE(hMutex == nullptr);
        goto InternalCreateMutexExit;
    }

    // Now that the object has been registered successfully, it would have a reference associated with the handle, so release
    // the initial reference. Any errors from now on need to revoke the handle.
    _ASSERTE(pobjRegisteredMutex == pobjMutex);
    _ASSERTE(hMutex != nullptr);
    pobjMutex->ReleaseReference(pthr);
    pobjRegisteredMutex = nullptr;

    if (lpName != nullptr)
    {
        SharedMemoryProcessDataHeader *processDataHeader;
        bool created = false;
        try
        {
            processDataHeader = NamedMutexProcessData::CreateOrOpen(lpName, !!bInitialOwner, &created);
        }
        catch (SharedMemoryException ex)
        {
            palError = ex.GetErrorCode();
            goto InternalCreateMutexExit;
        }
        SharedMemoryProcessDataHeader::PalObject_SetProcessDataHeader(pobjMutex, processDataHeader);

        if (!created)
        {
            // Indicate to the caller that an existing mutex was opened, and hence the caller will not have initial ownership
            // of the mutex if requested through bInitialOwner
            palError = ERROR_ALREADY_EXISTS;
        }
    }

    *phMutex = hMutex;
    hMutex = nullptr;
    pobjMutex = nullptr;

InternalCreateMutexExit:

    _ASSERTE(pobjRegisteredMutex == nullptr);
    if (hMutex != nullptr)
    {
        g_pObjectManager->RevokeHandle(pthr, hMutex);
    }
    else if (NULL != pobjMutex)
    {
        pobjMutex->ReleaseReference(pthr);
    }

    LOGEXIT("InternalCreateMutex returns %i\n", palError);

    return palError;
}
Esempio n. 5
0
PAL_ERROR
CorUnix::InternalReleaseMutex(
    CPalThread *pthr,
    HANDLE hMutex
    )
{
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pobjMutex = NULL;
    ISynchStateController *pssc = NULL;

    _ASSERTE(NULL != pthr);

    ENTRY("InternalReleaseMutex(pthr=%p, hMutex=%p)\n",
        pthr,
        hMutex
        );

    palError = g_pObjectManager->ReferenceObjectByHandle(
        pthr,
        hMutex,
        &aotMutex,
        0, // should be MUTEX_MODIFY_STATE -- current ignored (no Win32 security)
        &pobjMutex
        );

    if (NO_ERROR != palError)
    {
        ERROR("Unable to obtain object for handle %p (error %d)!\n", hMutex, palError);
        goto InternalReleaseMutexExit;
    }
    
    palError = pobjMutex->GetSynchStateController(
        pthr,
        &pssc
        );

    if (NO_ERROR != palError)
    {
        ASSERT("Error %d obtaining synch state controller\n", palError);
        goto InternalReleaseMutexExit;
    }

    palError = pssc->DecrementOwnershipCount();

    if (NO_ERROR != palError)
    {
        ERROR("Error %d decrementing mutex ownership count\n", palError);
        goto InternalReleaseMutexExit;
    }

InternalReleaseMutexExit:

    if (NULL != pssc)
    {
        pssc->ReleaseController();
    }

    if (NULL != pobjMutex)
    {
        pobjMutex->ReleaseReference(pthr);
    }

    LOGEXIT("InternalReleaseMutex returns %i\n", palError);

    return palError;
}
Esempio n. 6
0
PAL_ERROR
CorUnix::InternalCreateMutex(
    CPalThread *pthr,
    LPSECURITY_ATTRIBUTES lpMutexAttributes,
    BOOL bInitialOwner,
    LPCWSTR lpName,
    HANDLE *phMutex
    )
{
    CObjectAttributes oa(lpName, lpMutexAttributes);
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pobjMutex = NULL;
    IPalObject *pobjRegisteredMutex = NULL;
    ISynchStateController *pssc = NULL;

    _ASSERTE(NULL != pthr);
    _ASSERTE(NULL != phMutex);

    ENTRY("InternalCreateMutex(pthr=%p, lpMutexAttributes=%p, bInitialOwner=%d"
        ", lpName=%p, phMutex=%p)\n",
        pthr,
        lpMutexAttributes,
        bInitialOwner,
        lpName,
        phMutex
        );

    if (lpName != nullptr)
    {
        ASSERT("lpName: Cross-process named objects are not supported in PAL");
        palError = ERROR_NOT_SUPPORTED;
        goto InternalCreateMutexExit;
    }

    palError = g_pObjectManager->AllocateObject(
        pthr,
        &otMutex,
        &oa,
        &pobjMutex
        );

    if (NO_ERROR != palError)
    {
        goto InternalCreateMutexExit;
    }

    palError = pobjMutex->GetSynchStateController(
        pthr,
        &pssc
        );

    if (NO_ERROR != palError)
    {
        ASSERT("Unable to create state controller (%d)\n", palError);
        goto InternalCreateMutexExit;
    }

    if (bInitialOwner)
    {
        palError = pssc->SetOwner(pthr);
    }
    else
    {
        palError = pssc->SetSignalCount(1);
    }

    pssc->ReleaseController();

    if (NO_ERROR != palError)
    {
        ASSERT("Unable to set initial mutex state (%d)\n", palError);
        goto InternalCreateMutexExit;
    }

    palError = g_pObjectManager->RegisterObject(
        pthr,
        pobjMutex,
        &aotMutex, 
        0, // should be MUTEX_ALL_ACCESS -- currently ignored (no Win32 security)
        phMutex,
        &pobjRegisteredMutex
        );

    //
    // pobjMutex is invalidated by the call to RegisterObject, so NULL it
    // out here to ensure that we don't try to release a reference on
    // it down the line.
    //
    
    pobjMutex = NULL;

InternalCreateMutexExit:

    if (NULL != pobjMutex)
    {
        pobjMutex->ReleaseReference(pthr);
    }

    if (NULL != pobjRegisteredMutex)
    {
        pobjRegisteredMutex->ReleaseReference(pthr);
    }

    LOGEXIT("InternalCreateMutex returns %i\n", palError);

    return palError;
}