RTDECL(int) RTPipeRead(RTPIPE hPipe, void *pvBuf, size_t cbToRead, size_t *pcbRead) { RTPIPEINTERNAL *pThis = hPipe; AssertPtrReturn(pThis, VERR_INVALID_HANDLE); AssertReturn(pThis->u32Magic == RTPIPE_MAGIC, VERR_INVALID_HANDLE); AssertReturn(pThis->fRead, VERR_ACCESS_DENIED); AssertPtr(pcbRead); AssertPtr(pvBuf); int rc = rtPipeTryNonBlocking(pThis); if (RT_SUCCESS(rc)) { ssize_t cbRead = read(pThis->fd, pvBuf, RT_MIN(cbToRead, SSIZE_MAX)); if (cbRead >= 0) { if (cbRead || !cbToRead || !rtPipePosixHasHup(pThis)) *pcbRead = cbRead; else rc = VERR_BROKEN_PIPE; } else if (errno == EAGAIN) { *pcbRead = 0; rc = VINF_TRY_AGAIN; } else rc = RTErrConvertFromErrno(errno); ASMAtomicDecU32(&pThis->u32State); } return rc; }
/** * Uninitializes the instance and sets the ready flag to FALSE. * Called either from FinalRelease() or by the parent when it gets destroyed. */ void VirtualBoxClient::uninit() { LogFlowThisFunc(("\n")); /* Enclose the state transition Ready->InUninit->NotReady */ AutoUninitSpan autoUninitSpan(this); if (autoUninitSpan.uninitDone()) return; if (mData.m_ThreadWatcher != NIL_RTTHREAD) { /* Signal the event semaphore and wait for the thread to terminate. * if it hangs for some reason exit anyway, this can cause a crash * though as the object will no longer be available. */ RTSemEventSignal(mData.m_SemEvWatcher); RTThreadWait(mData.m_ThreadWatcher, 30000, NULL); mData.m_ThreadWatcher = NIL_RTTHREAD; RTSemEventDestroy(mData.m_SemEvWatcher); mData.m_SemEvWatcher = NIL_RTSEMEVENT; } mData.m_pVirtualBox.setNull(); ASMAtomicDecU32(&g_cInstances); }
int vboxVhwaHlpCheckTerm(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId) { Assert(VidPnSourceId < (D3DDDI_VIDEO_PRESENT_SOURCE_ID)VBoxCommonFromDeviceExt(pDevExt)->cDisplays); if (VidPnSourceId >= (D3DDDI_VIDEO_PRESENT_SOURCE_ID)VBoxCommonFromDeviceExt(pDevExt)->cDisplays) return VERR_INVALID_PARAMETER; PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[VidPnSourceId]; Assert(!!(pSource->Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED)); /** @todo need a better sync */ uint32_t cNew = ASMAtomicDecU32(&pSource->Vhwa.cOverlaysCreated); int rc = VINF_SUCCESS; if (!cNew) { rc = vboxVhwaHlpDestroyPrimary(pDevExt, pSource, VidPnSourceId); AssertRC(rc); } else { Assert(cNew < UINT32_MAX / 2); } return rc; }
RTDECL(int) RTPipeWrite(RTPIPE hPipe, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten) { RTPIPEINTERNAL *pThis = hPipe; AssertPtrReturn(pThis, VERR_INVALID_HANDLE); AssertReturn(pThis->u32Magic == RTPIPE_MAGIC, VERR_INVALID_HANDLE); AssertReturn(!pThis->fRead, VERR_ACCESS_DENIED); AssertPtr(pcbWritten); AssertPtr(pvBuf); int rc = rtPipeTryNonBlocking(pThis); if (RT_SUCCESS(rc)) { if (cbToWrite) { ssize_t cbWritten = write(pThis->fd, pvBuf, RT_MIN(cbToWrite, SSIZE_MAX)); if (cbWritten >= 0) *pcbWritten = cbWritten; else if (errno == EAGAIN) { *pcbWritten = 0; rc = VINF_TRY_AGAIN; } else rc = RTErrConvertFromErrno(errno); } else *pcbWritten = 0; ASMAtomicDecU32(&pThis->u32State); } return rc; }
RTDECL(int) RTSemMutexDestroy(RTSEMMUTEX hMutexSem) { /* * Validate input. */ PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)hMutexSem; if (!pThis) return VERR_INVALID_PARAMETER; AssertPtrReturn(pThis, VERR_INVALID_HANDLE); AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE); RT_ASSERT_INTS_ON(); /* * Kill it, wake up all waiting threads and release the reference. */ AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, ~RTSEMMUTEX_MAGIC, RTSEMMUTEX_MAGIC), VERR_INVALID_HANDLE); lck_spin_lock(pThis->pSpinlock); if (pThis->cWaiters > 0) thread_wakeup_prim((event_t)pThis, FALSE /* one_thread */, THREAD_RESTART); if (ASMAtomicDecU32(&pThis->cRefs) == 0) rtSemMutexDarwinFree(pThis); else lck_spin_unlock(pThis->pSpinlock); return VINF_SUCCESS; }
/** * Releases a reference to a RTMPNTONSPECIFICARGS heap allocation, freeing it * when the last reference is released. */ DECLINLINE(void) rtMpNtOnSpecificRelease(PRTMPNTONSPECIFICARGS pArgs) { uint32_t cRefs = ASMAtomicDecU32(&pArgs->cRefs); AssertMsg(cRefs <= 1, ("cRefs=%#x\n", cRefs)); if (cRefs == 0) ExFreePool(pArgs); }
/** * Release a reference, destroy the thing if necessary. * * @param pThis The semaphore. */ DECLINLINE(void) rtR0SemEventMultiHkuRelease(PRTSEMEVENTMULTIINTERNAL pThis) { if (RT_UNLIKELY(ASMAtomicDecU32(&pThis->cRefs) == 0)) { Assert(pThis->u32Magic != RTSEMEVENTMULTI_MAGIC); RTMemFree(pThis); } }
uint32_t i_release() { uint32_t cRefs = ASMAtomicDecU32(&m_cRefs); Assert(cRefs < _1K); if (cRefs == 0) delete this; return cRefs; }
void VBoxDispVHWACommandRelease(PVBOXDISPDEV pDev, VBOXVHWACMD* pCmd) { uint32_t cRefs = ASMAtomicDecU32(&pCmd->cRefs); Assert(cRefs < UINT32_MAX / 2); if(!cRefs) { VBoxDispVHWACommandFree(pDev, pCmd); } }
static uint32_t renderspuContextRelease( ContextInfo *context ) { uint32_t cRefs = ASMAtomicDecU32(&context->cRefs); if (!cRefs) renderspuDestroyContextTerminate( context ); else CRASSERT(cRefs < UINT32_MAX/2); return cRefs; }
static void vboxVhwaHlpOverlayListRemove(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_OVERLAY pOverlay) { PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pOverlay->VidPnSourceId]; KIRQL OldIrql; KeAcquireSpinLock(&pSource->OverlayListLock, &OldIrql); ASMAtomicDecU32(&pSource->cOverlays); RemoveEntryList(&pOverlay->ListEntry); KeReleaseSpinLock(&pSource->OverlayListLock, OldIrql); }
/** * Release a reference, destroy the thing if necessary. * * @param pThis The semaphore. */ DECLINLINE(void) rtR0SemEventMultiDarwinRelease(PRTSEMEVENTMULTIINTERNAL pThis) { if (RT_UNLIKELY(ASMAtomicDecU32(&pThis->cRefs) == 0)) { Assert(pThis->u32Magic != RTSEMEVENTMULTI_MAGIC); lck_spin_destroy(pThis->pSpinlock, g_pDarwinLockGroup); RTMemFree(pThis); } }
DECLINLINE(void) vbvaVhwaCommandRelease(PVBOXMP_DEVEXT pDevExt, VBOXVHWACMD* pCmd) { uint32_t cRefs = ASMAtomicDecU32(&pCmd->cRefs); Assert(cRefs < UINT32_MAX / 2); if(!cRefs) { VBoxHGSMIBufferFree(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx, pCmd); } }
DECLINLINE(VOID) vboxWddmSwapchainRelease(PVBOXWDDM_SWAPCHAIN pSwapchain) { const uint32_t cRefs = ASMAtomicDecU32(&pSwapchain->cRefs); Assert(cRefs < UINT32_MAX/2); if (!cRefs) { vboxWddmMemFree(pSwapchain); } }
/** * Removes the thread from the AVL tree, call owns the tree lock * and has cleared the RTTHREADINT_FLAG_IN_TREE bit. * * @param pThread The thread to remove. */ static void rtThreadRemoveLocked(PRTTHREADINT pThread) { PRTTHREADINT pThread2 = (PRTTHREADINT)RTAvlPVRemove(&g_ThreadTree, pThread->Core.Key); #if !defined(RT_OS_OS2) /** @todo this asserts for threads created by NSPR */ AssertMsg(pThread2 == pThread, ("%p(%s) != %p (%p/%s)\n", pThread2, pThread2 ? pThread2->szName : "<null>", pThread, pThread->Core.Key, pThread->szName)); #endif if (pThread2) ASMAtomicDecU32(&g_cThreadInTree); }
RTDECL(int) RTSemMutexRelease(RTSEMMUTEX hMutexSem) { /* * Validate input. */ struct RTSEMMUTEXINTERNAL *pThis = hMutexSem; AssertPtrReturn(pThis, VERR_INVALID_HANDLE); AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); #ifdef RTSEMMUTEX_STRICT int rc9 = RTLockValidatorRecExclReleaseOwner(&pThis->ValidatorRec, pThis->cNesting == 1); if (RT_FAILURE(rc9)) return rc9; #endif /* * Check if nested. */ pthread_t Self = pthread_self(); if (RT_UNLIKELY( pThis->Owner != Self || pThis->cNesting == 0)) { AssertMsgFailed(("Not owner of mutex %p!! Self=%08x Owner=%08x cNesting=%d\n", pThis, Self, pThis->Owner, pThis->cNesting)); return VERR_NOT_OWNER; } /* * If nested we'll just pop a nesting. */ if (pThis->cNesting > 1) { ASMAtomicDecU32(&pThis->cNesting); return VINF_SUCCESS; } /* * Clear the state. (cNesting == 1) */ pThis->Owner = (pthread_t)-1; ASMAtomicWriteU32(&pThis->cNesting, 0); /* * Unlock mutex semaphore. */ int rc = pthread_mutex_unlock(&pThis->Mutex); if (RT_UNLIKELY(rc)) { AssertMsgFailed(("Failed to unlock mutex sem %p, rc=%d.\n", hMutexSem, rc)); NOREF(rc); return RTErrConvertFromErrno(rc); } return VINF_SUCCESS; }
RTDECL(int) RTSemMutexRelease(RTSEMMUTEX hMutexSem) { /* * Validate input. */ struct RTSEMMUTEXINTERNAL *pThis = hMutexSem; AssertPtrReturn(pThis, VERR_INVALID_HANDLE); AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); #ifdef RTSEMMUTEX_STRICT int rc9 = RTLockValidatorRecExclReleaseOwner(&pThis->ValidatorRec, pThis->cNestings == 1); if (RT_FAILURE(rc9)) return rc9; #endif /* * Check if nested. */ pthread_t Self = pthread_self(); if (RT_UNLIKELY( pThis->Owner != Self || pThis->cNestings == 0)) { AssertMsgFailed(("Not owner of mutex %p!! Self=%08x Owner=%08x cNestings=%d\n", pThis, Self, pThis->Owner, pThis->cNestings)); return VERR_NOT_OWNER; } /* * If nested we'll just pop a nesting. */ if (pThis->cNestings > 1) { ASMAtomicDecU32(&pThis->cNestings); return VINF_SUCCESS; } /* * Clear the state. (cNestings == 1) */ pThis->Owner = (pthread_t)~0; ASMAtomicWriteU32(&pThis->cNestings, 0); /* * Release the mutex. */ int32_t iNew = ASMAtomicDecS32(&pThis->iState); if (RT_UNLIKELY(iNew != 0)) { /* somebody is waiting, try wake up one of them. */ ASMAtomicXchgS32(&pThis->iState, 0); (void)sys_futex(&pThis->iState, FUTEX_WAKE, 1, NULL, NULL, 0); } return VINF_SUCCESS; }
/** * Releases the instance data. * * @param pThis The instance data. */ static void rtDbgModDeferredReleaseInstanceData(PRTDBGMODDEFERRED pThis) { AssertPtr(pThis); uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs); Assert(cRefs < 8); if (!cRefs) { RTDbgCfgRelease(pThis->hDbgCfg); pThis->hDbgCfg = NIL_RTDBGCFG; RTMemFree(pThis); } }
/** * Close a file device previously opened by VBoxDrvFreeBSDOpen * * @returns 0 on success. * @param pDev The device. * @param fFile The file descriptor flags. * @param DevType The device type (CHR. * @param pTd The calling thread. */ static void VBoxDrvFreeBSDDtr(void *pData) { PSUPDRVSESSION pSession = pData; Log(("VBoxDrvFreeBSDDtr: pSession=%p\n", pSession)); /* * Close the session. */ supdrvSessionRelease(pSession); ASMAtomicDecU32(&g_cUsers); }
uint32_t SecretKey::release() { uint32_t cRefs = ASMAtomicDecU32(&m_cRefs); if (!cRefs) { int rc = RTMemSaferScramble(m_pbKey, m_cbKey); AssertRC(rc); } return cRefs; }
RTDECL(int) RTSemRWReleaseRead(RTSEMRW hRWSem) { /* * Validate input. */ struct RTSEMRWINTERNAL *pThis = hRWSem; AssertPtrReturn(pThis, VERR_INVALID_HANDLE); AssertMsgReturn(pThis->u32Magic == RTSEMRW_MAGIC, ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE); /* * Check if it's the writer. */ pthread_t Self = pthread_self(); pthread_t Writer; ATOMIC_GET_PTHREAD_T(&pThis->Writer, &Writer); if (Writer == Self) { AssertMsgReturn(pThis->cWriterReads > 0, ("pThis=%p\n", pThis), VERR_NOT_OWNER); #ifdef RTSEMRW_STRICT int rc9 = RTLockValidatorRecExclUnwindMixed(&pThis->ValidatorWrite, &pThis->ValidatorRead.Core); if (RT_FAILURE(rc9)) return rc9; #endif pThis->cWriterReads--; return VINF_SUCCESS; } /* * Try unlock it. */ #ifdef RTSEMRW_STRICT int rc9 = RTLockValidatorRecSharedCheckAndRelease(&pThis->ValidatorRead, RTThreadSelf()); if (RT_FAILURE(rc9)) return rc9; #endif #ifdef RT_OS_LINUX /* glibc (at least 2.8) may screw up when unlocking a lock we don't own. */ if (ASMAtomicReadU32(&pThis->cReaders) == 0) { AssertMsgFailed(("Not owner of %p\n", pThis)); return VERR_NOT_OWNER; } #endif ASMAtomicDecU32(&pThis->cReaders); int rc = pthread_rwlock_unlock(&pThis->RWLock); if (rc) { ASMAtomicIncU32(&pThis->cReaders); AssertMsgFailed(("Failed read unlock read-write sem %p, rc=%d.\n", hRWSem, rc)); return RTErrConvertFromErrno(rc); } return VINF_SUCCESS; }
/** * Release a reference to the module. * * When the reference count reaches zero, the module is destroyed. * * @returns New reference count, UINT32_MAX on invalid handle (asserted). * * @param hDbgMod The module handle. The NIL handle is quietly ignored * and 0 is returned. * * @remarks Will not take any locks. */ RTDECL(uint32_t) RTDbgModRelease(RTDBGMOD hDbgMod) { if (hDbgMod == NIL_RTDBGMOD) return 0; PRTDBGMODINT pDbgMod = hDbgMod; RTDBGMOD_VALID_RETURN_RC(pDbgMod, UINT32_MAX); uint32_t cRefs = ASMAtomicDecU32(&pDbgMod->cRefs); if (!cRefs) rtDbgModDestroy(pDbgMod); return cRefs; }
INTNETR3DECL(int) SUPR0ObjRelease(void *pvObj, PSUPDRVSESSION pSession) { RTTEST_CHECK_RET(g_hTest, pSession == g_pSession, VERR_INVALID_PARAMETER); POBJREF pRef = (POBJREF)pvObj; if (!ASMAtomicDecU32(&pRef->cRefs)) { pRef->pfnDestructor(pRef, pRef->pvUser1, pRef->pvUser2); RTTestGuardedFree(g_hTest, pRef); return VINF_OBJECT_DESTROYED; } return VINF_SUCCESS; }
/** * Destroys the per thread data. * * @param pThread The thread to destroy. */ static void rtThreadDestroy(PRTTHREADINT pThread) { RTSEMEVENTMULTI hEvt1, hEvt2; /* * Remove it from the tree and mark it as dead. * * Threads that has seen rtThreadTerminate and should already have been * removed from the tree. There is probably no thread that should * require removing here. However, be careful making sure that cRefs * isn't 0 if we do or we'll blow up because the strict locking code * will be calling us back. */ if (ASMBitTest(&pThread->fIntFlags, RTTHREADINT_FLAG_IN_TREE_BIT)) { ASMAtomicIncU32(&pThread->cRefs); rtThreadRemove(pThread); ASMAtomicDecU32(&pThread->cRefs); } /* * Invalidate the thread structure. */ #ifdef IN_RING3 rtLockValidatorSerializeDestructEnter(); rtLockValidatorDeletePerThread(&pThread->LockValidator); #endif #ifdef RT_WITH_ICONV_CACHE rtStrIconvCacheDestroy(pThread); #endif ASMAtomicXchgU32(&pThread->u32Magic, RTTHREADINT_MAGIC_DEAD); ASMAtomicWritePtr(&pThread->Core.Key, (void *)NIL_RTTHREAD); pThread->enmType = RTTHREADTYPE_INVALID; hEvt1 = pThread->EventUser; pThread->EventUser = NIL_RTSEMEVENTMULTI; hEvt2 = pThread->EventTerminated; pThread->EventTerminated = NIL_RTSEMEVENTMULTI; #ifdef IN_RING3 rtLockValidatorSerializeDestructLeave(); #endif /* * Destroy semaphore resources and free the bugger. */ RTSemEventMultiDestroy(hEvt1); if (hEvt2 != NIL_RTSEMEVENTMULTI) RTSemEventMultiDestroy(hEvt2); rtThreadNativeDestroy(pThread); RTMemFree(pThread); }
static DECLCALLBACK(void) AsyncTaskCompleted(PVM pVM, void *pvUser, void *pvUser2, int rc) { LogFlow((TESTCASE ": %s: pVM=%p pvUser=%p pvUser2=%p\n", __FUNCTION__, pVM, pvUser, pvUser2)); NOREF(rc); uint32_t cTasksStillLeft = ASMAtomicDecU32(&g_cTasksLeft); if (!cTasksStillLeft) { /* All tasks processed. Wakeup main. */ RTSemEventSignal(g_FinishedEventSem); } }
RTDECL(uint32_t) RTKrnlModInfoRelease(RTKRNLMODINFO hKrnlModInfo) { PRTKRNLMODINFOINT pThis = hKrnlModInfo; if (!pThis) return 0; AssertPtrReturn(pThis, UINT32_MAX); uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs); AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pThis)); if (cRefs == 0) rtKrnlModInfoDestroy(pThis); return cRefs; }
/** * Prepare non-blocking mode. * * @returns VINF_SUCCESS * @retval VERR_WRONG_ORDER * @retval VERR_INTERNAL_ERROR_4 * * @param pThis The pipe handle. */ static int rtPipeTryNonBlocking(RTPIPEINTERNAL *pThis) { /* * Update the state. */ for (;;) { uint32_t u32State = ASMAtomicReadU32(&pThis->u32State); uint32_t const u32StateOld = u32State; uint32_t const cUsers = (u32State & RTPIPE_POSIX_USERS_MASK); if (!(u32State & RTPIPE_POSIX_BLOCKING)) { AssertReturn(cUsers < RTPIPE_POSIX_USERS_MASK / 2, VERR_INTERNAL_ERROR_4); u32State &= ~RTPIPE_POSIX_USERS_MASK; u32State |= cUsers + 1; if (ASMAtomicCmpXchgU32(&pThis->u32State, u32State, u32StateOld)) { if (u32State & RTPIPE_POSIX_SWITCHING) break; return VINF_SUCCESS; } } else if (cUsers == 0) { u32State = 1 | RTPIPE_POSIX_SWITCHING; if (ASMAtomicCmpXchgU32(&pThis->u32State, u32State, u32StateOld)) break; } else return VERR_WRONG_ORDER; ASMNopPause(); } /* * Do the switching. */ int fFlags = fcntl(pThis->fd, F_GETFL, 0); if (fFlags != -1) { if ( (fFlags & O_NONBLOCK) || fcntl(pThis->fd, F_SETFL, fFlags | O_NONBLOCK) != -1) { ASMAtomicBitClear(&pThis->u32State, RTPIPE_POSIX_SWITCHING_BIT); return VINF_SUCCESS; } } ASMAtomicDecU32(&pThis->u32State); return RTErrConvertFromErrno(errno); }
VBGLR3DECL(void) VbglR3Term(void) { /* * Decrement the reference count and see if we're the last one out. */ uint32_t cInits = ASMAtomicDecU32(&g_cInits); if (cInits > 0) return; #if !defined(VBOX_VBGLR3_XSERVER) AssertReturnVoid(!cInits); # if defined(RT_OS_WINDOWS) HANDLE hFile = g_hFile; g_hFile = INVALID_HANDLE_VALUE; AssertReturnVoid(hFile != INVALID_HANDLE_VALUE); BOOL fRc = CloseHandle(hFile); Assert(fRc); NOREF(fRc); # elif defined(RT_OS_OS2) RTFILE File = g_File; g_File = NIL_RTFILE; AssertReturnVoid(File != NIL_RTFILE); APIRET rc = DosClose((uintptr_t)File); AssertMsg(!rc, ("%ld\n", rc)); #elif defined(RT_OS_DARWIN) io_connect_t uConnection = g_uConnection; RTFILE hFile = g_File; g_uConnection = 0; g_File = NIL_RTFILE; kern_return_t kr = IOServiceClose(uConnection); AssertMsg(kr == kIOReturnSuccess, ("%#x (%d)\n", kr, kr)); int rc = RTFileClose(hFile); AssertRC(rc); # else /* The IPRT case. */ RTFILE File = g_File; g_File = NIL_RTFILE; AssertReturnVoid(File != NIL_RTFILE); int rc = RTFileClose(File); AssertRC(rc); # endif #else /* VBOX_VBGLR3_XSERVER */ int File = g_File; g_File = -1; if (File == -1) return; xf86close(File); #endif /* VBOX_VBGLR3_XSERVER */ }
/** * @callback_method_impl{dtrace_pops_t,dtps_disable} */ static void vboxDtPOps_Disable(void *pvProv, dtrace_id_t idProbe, void *pvProbe) { PSUPDRVVDTPROVIDERCORE pProv = (PSUPDRVVDTPROVIDERCORE)pvProv; AssertPtrReturnVoid(pProv); LOG_DTRACE(("%s: %p / %p - %#x / %p\n", __FUNCTION__, pProv, pProv->TracerData.DTrace.idProvider, idProbe, pvProbe)); AssertPtrReturnVoid(pProv->TracerData.DTrace.idProvider); if (!pProv->TracerData.DTrace.fZombie) { uint32_t idxProbeLoc = (uint32_t)(uintptr_t)pvProbe; PVTGPROBELOC32 pProbeLocEn = (PVTGPROBELOC32)( (uintptr_t)pProv->pvProbeLocsEn + idxProbeLoc * pProv->cbProbeLocsEn); PCVTGPROBELOC pProbeLocRO = (PVTGPROBELOC)&pProv->paProbeLocsRO[idxProbeLoc]; PCVTGDESCPROBE pProbeDesc = pProbeLocRO->pProbe; uint32_t const idxProbe = pProbeDesc->idxEnabled; if (!pProv->fUmod) { if (pProbeLocEn->fEnabled) { pProbeLocEn->fEnabled = 0; ASMAtomicDecU32(&pProv->pacProbeEnabled[idxProbe]); } } else { /* Update kernel mode structure */ if (pProv->paR0ProbeLocs[idxProbeLoc].fEnabled) { pProv->paR0ProbeLocs[idxProbeLoc].fEnabled = 0; ASMAtomicDecU32(&pProv->paR0Probes[idxProbe].cEnabled); } /* Update user mode structure. */ pProbeLocEn->fEnabled = 0; pProv->pacProbeEnabled[idxProbe] = pProv->paR0Probes[idxProbe].cEnabled; } } }
RTDECL(int) RTSemMutexRelease(RTSEMMUTEX hMutexSem) { /* * Validate. */ RTSEMMUTEXINTERNAL *pThis = hMutexSem; AssertPtrReturn(pThis, VERR_INVALID_HANDLE); AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE); /* * Check ownership and recursions. */ RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf(); RTNATIVETHREAD hNativeOwner; ASMAtomicReadHandle(&pThis->hNativeOwner, &hNativeOwner); if (RT_UNLIKELY(hNativeOwner != hNativeSelf)) { AssertMsgFailed(("Not owner of mutex %p!! hNativeSelf=%RTntrd Owner=%RTntrd cRecursions=%d\n", pThis, hNativeSelf, hNativeOwner, pThis->cRecursions)); return VERR_NOT_OWNER; } if (pThis->cRecursions > 1) { #ifdef RTSEMMUTEX_STRICT int rc9 = RTLockValidatorRecExclUnwind(&pThis->ValidatorRec); if (RT_FAILURE(rc9)) return rc9; #endif ASMAtomicDecU32(&pThis->cRecursions); return VINF_SUCCESS; } /* * Unlock mutex semaphore. */ #ifdef RTSEMMUTEX_STRICT int rc9 = RTLockValidatorRecExclReleaseOwner(&pThis->ValidatorRec, false); if (RT_FAILURE(rc9)) return rc9; #endif ASMAtomicWriteU32(&pThis->cRecursions, 0); ASMAtomicWriteHandle(&pThis->hNativeOwner, NIL_RTNATIVETHREAD); if (ReleaseMutex(pThis->hMtx)) return VINF_SUCCESS; int rc = RTErrConvertFromWin32(GetLastError()); AssertMsgFailed(("%p/%p, rc=%Rrc lasterr=%d\n", pThis, pThis->hMtx, rc, GetLastError())); return rc; }