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; }
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; }