/** * Allocates and acquires the lock for the stream. * * @returns IPRT status. * @param pStream The stream (valid). */ static int rtStrmAllocLock(PRTSTREAM pStream) { Assert(pStream->pCritSect == NULL); PRTCRITSECT pCritSect = (PRTCRITSECT)RTMemAlloc(sizeof(*pCritSect)); if (!pCritSect) return VERR_NO_MEMORY; /* The native stream lock are normally not recursive. */ int rc = RTCritSectInitEx(pCritSect, RTCRITSECT_FLAGS_NO_NESTING, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, "RTSemSpinMutex"); if (RT_SUCCESS(rc)) { rc = RTCritSectEnter(pCritSect); if (RT_SUCCESS(rc)) { if (RT_LIKELY(ASMAtomicCmpXchgPtr(&pStream->pCritSect, pCritSect, NULL))) return VINF_SUCCESS; RTCritSectLeave(pCritSect); } RTCritSectDelete(pCritSect); } RTMemFree(pCritSect); /* Handle the lost race case... */ pCritSect = ASMAtomicReadPtrT(&pStream->pCritSect, PRTCRITSECT); if (pCritSect) return RTCritSectEnter(pCritSect); return rc; }
/** * Allocates a Solaris URB request structure. * * @returns Pointer to an active URB request. * @returns NULL on failure. * * @param pDevSol The solaris USB device. */ static PUSBPROXYURBSOL usbProxySolarisUrbAlloc(PUSBPROXYDEVSOL pDevSol) { PUSBPROXYURBSOL pUrbSol; RTCritSectEnter(&pDevSol->CritSect); /* * Try remove a Solaris URB from the free list, if none there allocate a new one. */ pUrbSol = pDevSol->pFreeHead; if (pUrbSol) pDevSol->pFreeHead = pUrbSol->pNext; else { RTCritSectLeave(&pDevSol->CritSect); pUrbSol = (PUSBPROXYURBSOL)RTMemAlloc(sizeof(*pUrbSol)); if (!pUrbSol) return NULL; RTCritSectEnter(&pDevSol->CritSect); } pUrbSol->pVUsbUrb = NULL; pUrbSol->pDevSol = pDevSol; /* * Link it into the active list */ pUrbSol->pPrev = NULL; pUrbSol->pNext = pDevSol->pInFlightHead; if (pUrbSol->pNext) pUrbSol->pNext->pPrev = pUrbSol; pDevSol->pInFlightHead = pUrbSol; RTCritSectLeave(&pDevSol->CritSect); return pUrbSol; }
static void pdmNsFilterUnlink(PPDMNSFILTER pFilter) { PPDMNSBWGROUP pBwGroup = pFilter->pBwGroupR3; /* * We need to make sure we hold the shaper lock since pdmNsBwGroupXmitPending() * does not hold the bandwidth group lock while iterating over the list * of group's filters. */ AssertPtr(pBwGroup); AssertPtr(pBwGroup->pShaper); Assert(RTCritSectIsOwner(&pBwGroup->pShaper->cs)); int rc = RTCritSectEnter(&pBwGroup->cs); AssertRC(rc); if (pFilter == pBwGroup->pFiltersHead) pBwGroup->pFiltersHead = pFilter->pNext; else { PPDMNSFILTER pPrev = pBwGroup->pFiltersHead; while ( pPrev && pPrev->pNext != pFilter) pPrev = pPrev->pNext; AssertPtr(pPrev); pPrev->pNext = pFilter->pNext; } rc = RTCritSectLeave(&pBwGroup->cs); AssertRC(rc); }
/** * Suspend all running threads. * * This is called by PDMR3Suspend() and PDMR3PowerOff() after all the devices * and drivers have been notified about the suspend / power off. * * @return VBox status code. * @param pVM Pointer to the VM. */ int pdmR3ThreadSuspendAll(PVM pVM) { PUVM pUVM = pVM->pUVM; RTCritSectEnter(&pUVM->pdm.s.ListCritSect); /* This may cause deadlocks later... */ for (PPDMTHREAD pThread = pUVM->pdm.s.pThreads; pThread; pThread = pThread->Internal.s.pNext) switch (pThread->enmState) { case PDMTHREADSTATE_RUNNING: { int rc = PDMR3ThreadSuspend(pThread); AssertRCReturn(rc, rc); break; } /* suspend -> power off; voluntary suspend. */ case PDMTHREADSTATE_SUSPENDED: break; default: AssertMsgFailed(("pThread=%p enmState=%d\n", pThread, pThread->enmState)); break; } RTCritSectLeave(&pUVM->pdm.s.ListCritSect); return VINF_SUCCESS; }
/** * Deletes the critical section. * * @returns VBox status code. * @param pCritSect The PDM critical section to destroy. */ VMMR3DECL(int) PDMR3CritSectDelete(PPDMCRITSECT pCritSect) { if (!RTCritSectIsInitialized(&pCritSect->s.Core)) return VINF_SUCCESS; /* * Find and unlink it. */ PVM pVM = pCritSect->s.pVMR3; PUVM pUVM = pVM->pUVM; AssertReleaseReturn(pVM, VERR_PDM_CRITSECT_IPE); PPDMCRITSECTINT pPrev = NULL; RTCritSectEnter(&pUVM->pdm.s.ListCritSect); PPDMCRITSECTINT pCur = pUVM->pdm.s.pCritSects; while (pCur) { if (pCur == &pCritSect->s) { int rc = pdmR3CritSectDeleteOne(pVM, pUVM, pCur, pPrev, false /* not final */); RTCritSectLeave(&pUVM->pdm.s.ListCritSect); return rc; } /* next */ pPrev = pCur; pCur = pCur->pNext; } RTCritSectLeave(&pUVM->pdm.s.ListCritSect); AssertReleaseMsgFailed(("pCritSect=%p wasn't found!\n", pCritSect)); return VERR_PDM_CRITSECT_NOT_FOUND; }
/** * Deletes all critical sections with a give initializer key. * * @returns VBox status code. * The entire list is processed on failure, so we'll only * return the first error code. This shouldn't be a problem * since errors really shouldn't happen here. * @param pVM Pointer to the VM. * @param pvKey The initializer key. */ static int pdmR3CritSectDeleteByKey(PVM pVM, void *pvKey) { /* * Iterate the list and match key. */ PUVM pUVM = pVM->pUVM; int rc = VINF_SUCCESS; PPDMCRITSECTINT pPrev = NULL; RTCritSectEnter(&pUVM->pdm.s.ListCritSect); PPDMCRITSECTINT pCur = pUVM->pdm.s.pCritSects; while (pCur) { if (pCur->pvKey == pvKey) { int rc2 = pdmR3CritSectDeleteOne(pVM, pUVM, pCur, pPrev, false /* not final */); AssertRC(rc2); if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) rc = rc2; } /* next */ pPrev = pCur; pCur = pCur->pNext; } RTCritSectLeave(&pUVM->pdm.s.ListCritSect); return rc; }
int VBoxCredPoller::credentialsRetrieve(void) { credentialsReset(); /* Get credentials. */ RTCritSectEnter(&m_csCredUpate); int rc = VbglR3CredentialsRetrieve(&m_pszUser, &m_pszPw, &m_pszDomain); if (RT_SUCCESS(rc)) { /* NULL/free domain if it's empty (""). */ if (m_pszDomain && strlen(m_pszDomain) == 0) { RTStrFree(m_pszDomain); m_pszDomain = NULL; } Log(("VBoxCredPoller::credentialsRetrieve: Credentials retrieved (User=%s, Password=%s, Domain=%s)\n", m_pszUser ? m_pszUser : "******", m_pszPw ? m_pszPw : "<empty>", m_pszDomain ? m_pszDomain : "NULL")); AssertPtr(m_pProv); m_pProv->OnCredentialsProvided(); } RTCritSectLeave(&m_csCredUpate); return rc; }
/** * Destroys a async I/O manager. * * @returns nothing. * @param pAioMgr The async I/O manager to destroy. */ static void pdmacFileAioMgrDestroy(PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile, PPDMACEPFILEMGR pAioMgr) { int rc = pdmacFileAioMgrShutdown(pAioMgr); AssertRC(rc); /* Unlink from the list. */ rc = RTCritSectEnter(&pEpClassFile->CritSect); AssertRC(rc); PPDMACEPFILEMGR pPrev = pAioMgr->pPrev; PPDMACEPFILEMGR pNext = pAioMgr->pNext; if (pPrev) pPrev->pNext = pNext; else pEpClassFile->pAioMgrHead = pNext; if (pNext) pNext->pPrev = pPrev; pEpClassFile->cAioMgrs--; rc = RTCritSectLeave(&pEpClassFile->CritSect); AssertRC(rc); /* Free the resources. */ RTCritSectDelete(&pAioMgr->CritSectBlockingEvent); RTSemEventDestroy(pAioMgr->EventSem); if (pAioMgr->enmMgrType != PDMACEPFILEMGRTYPE_SIMPLE) pdmacFileAioMgrNormalDestroy(pAioMgr); MMR3HeapFree(pAioMgr); }
/** * Start a short critical section. */ sys_prot_t sys_arch_protect(void) { int rc; rc = RTCritSectEnter(&g_ProtCritSect); AssertRC(rc); return NULL; }
/** * @interface_method_impl{TXSTRANSPORT,pfnTerm} */ static DECLCALLBACK(void) txsTcpTerm(void) { /* Signal thread */ if (RTCritSectIsInitialized(&g_TcpCritSect)) { RTCritSectEnter(&g_TcpCritSect); g_fTcpStopConnecting = true; RTCritSectLeave(&g_TcpCritSect); } if (g_hThreadTcpConnect != NIL_RTTHREAD) { RTThreadUserSignal(g_hThreadTcpConnect); RTTcpClientCancelConnect(&g_pTcpConnectCancelCookie); } /* Shut down the server (will wake up thread). */ if (g_pTcpServer) { Log(("txsTcpTerm: Destroying server...\n")); int rc = RTTcpServerDestroy(g_pTcpServer); if (RT_FAILURE(rc)) RTMsgInfo("RTTcpServerDestroy failed in txsTcpTerm: %Rrc", rc); g_pTcpServer = NULL; } /* Shut down client */ if (g_hTcpClient != NIL_RTSOCKET) { if (g_fTcpClientFromServer) { Log(("txsTcpTerm: Disconnecting client...\n")); int rc = RTTcpServerDisconnectClient2(g_hTcpClient); if (RT_FAILURE(rc)) RTMsgInfo("RTTcpServerDisconnectClient2(%RTsock) failed in txsTcpTerm: %Rrc", g_hTcpClient, rc); } else { int rc = RTTcpClientClose(g_hTcpClient); if (RT_FAILURE(rc)) RTMsgInfo("RTTcpClientClose(%RTsock) failed in txsTcpTerm: %Rrc", g_hTcpClient, rc); } g_hTcpClient = NIL_RTSOCKET; } /* Clean up stashing. */ RTMemFree(g_pbTcpStashed); g_pbTcpStashed = NULL; g_cbTcpStashed = 0; g_cbTcpStashedAlloced = 0; /* Wait for the thread (they should've had some time to quit by now). */ txsTcpConnectWaitOnThreads(15000); /* Finally, clean up the critical section. */ if (RTCritSectIsInitialized(&g_TcpCritSect)) RTCritSectDelete(&g_TcpCritSect); Log(("txsTcpTerm: done\n")); }
int GuestBase::signalWaitEvents(VBoxEventType_T aType, IEvent *aEvent) { int rc = RTCritSectEnter(&mWaitEventCritSect); if (RT_SUCCESS(rc)) { GuestWaitEventTypes::iterator itTypes = mWaitEvents.find(aType); if (itTypes != mWaitEvents.end()) { for (GuestWaitEvents::iterator itEvents = itTypes->second.begin(); itEvents != itTypes->second.end(); itEvents++) { ComPtr<IEvent> pThisEvent = aEvent; Assert(!pThisEvent.isNull()); int rc2 = (*itEvents)->Signal(aEvent); if (RT_SUCCESS(rc)) rc = rc2; } } int rc2 = RTCritSectLeave(&mWaitEventCritSect); if (RT_SUCCESS(rc)) rc = rc2; } return rc; }
/** * Frees a Solaris URB request structure. * * @param pDevSol The Solaris USB device. * @param pUrbSol The Solaris URB to free. */ static void usbProxySolarisUrbFree(PUSBPROXYDEVSOL pDevSol, PUSBPROXYURBSOL pUrbSol) { RTCritSectEnter(&pDevSol->CritSect); /* * Remove from the active or taxing list. */ if (pUrbSol->pNext) pUrbSol->pNext->pPrev = pUrbSol->pPrev; else if (pDevSol->pTaxingTail == pUrbSol) pDevSol->pTaxingTail = pUrbSol->pPrev; if (pUrbSol->pPrev) pUrbSol->pPrev->pNext = pUrbSol->pNext; else if (pDevSol->pTaxingHead == pUrbSol) pDevSol->pTaxingHead = pUrbSol->pNext; else if (pDevSol->pInFlightHead == pUrbSol) pDevSol->pInFlightHead = pUrbSol->pNext; else AssertFailed(); /* * Link it into the free list. */ pUrbSol->pPrev = NULL; pUrbSol->pNext = pDevSol->pFreeHead; pDevSol->pFreeHead = pUrbSol; pUrbSol->pVUsbUrb = NULL; pUrbSol->pDevSol = NULL; RTCritSectLeave(&pDevSol->CritSect); }
RTDECL(int) RTPipeClose(RTPIPE hPipe) { RTPIPEINTERNAL *pThis = hPipe; if (pThis == NIL_RTPIPE) return VINF_SUCCESS; AssertPtrReturn(pThis, VERR_INVALID_PARAMETER); AssertReturn(pThis->u32Magic == RTPIPE_MAGIC, VERR_INVALID_HANDLE); /* * Do the cleanup. */ AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, ~RTPIPE_MAGIC, RTPIPE_MAGIC), VERR_INVALID_HANDLE); RTCritSectEnter(&pThis->CritSect); Assert(pThis->cUsers == 0); if (!pThis->fRead && pThis->fIOPending) rtPipeWriteCheckCompletion(pThis); CloseHandle(pThis->hPipe); pThis->hPipe = INVALID_HANDLE_VALUE; CloseHandle(pThis->Overlapped.hEvent); pThis->Overlapped.hEvent = NULL; RTMemFree(pThis->pbBounceBuf); pThis->pbBounceBuf = NULL; RTCritSectLeave(&pThis->CritSect); RTCritSectDelete(&pThis->CritSect); RTMemFree(pThis); return VINF_SUCCESS; }
/** * Enumerate all the register info handlers. * * @returns VBox status code. * @param pVM Pointer to the VM. * @param pfnCallback Pointer to callback function. * @param pvUser User argument to pass to the callback. */ VMMR3DECL(int) DBGFR3InfoEnum(PVM pVM, PFNDBGFINFOENUM pfnCallback, void *pvUser) { LogFlow(("DBGFR3InfoLog: pfnCallback=%p pvUser=%p\n", pfnCallback, pvUser)); /* * Validate input. */ if (!pfnCallback) { AssertMsgFailed(("!pfnCallback\n")); return VERR_INVALID_PARAMETER; } /* * Enter and enumerate. */ int rc = RTCritSectEnter(&pVM->dbgf.s.InfoCritSect); AssertRC(rc); rc = VINF_SUCCESS; for (PDBGFINFO pInfo = pVM->dbgf.s.pInfoFirst; RT_SUCCESS(rc) && pInfo; pInfo = pInfo->pNext) rc = pfnCallback(pVM, pInfo->szName, pInfo->pszDesc, pvUser); /* * Leave and exit. */ int rc2 = RTCritSectLeave(&pVM->dbgf.s.InfoCritSect); AssertRC(rc2); LogFlow(("DBGFR3InfoLog: returns %Rrc\n", rc)); return rc; }
RTDECL(int) RTLocalIpcSessionClose(RTLOCALIPCSESSION hSession) { /* * Validate input. */ if (hSession == NIL_RTLOCALIPCSESSION) return VINF_SUCCESS; PRTLOCALIPCSESSIONINT pThis = (PRTLOCALIPCSESSIONINT)hSession; AssertPtrReturn(pThis, VERR_INVALID_HANDLE); AssertReturn(pThis->u32Magic == RTLOCALIPCSESSION_MAGIC, VERR_INVALID_MAGIC); /* * Cancel any thread currently busy using the session, * leaving the cleanup to it. */ RTCritSectEnter(&pThis->CritSect); ASMAtomicUoWriteU32(&pThis->u32Magic, ~RTLOCALIPCSESSION_MAGIC); ASMAtomicUoWriteBool(&pThis->fCancelled, true); pThis->cRefs--; if (pThis->cRefs > 0) { BOOL fRc = SetEvent(pThis->hEvent); AssertMsg(fRc, ("%d\n", GetLastError())); NOREF(fRc); RTCritSectLeave(&pThis->CritSect); } else rtLocalIpcSessionWinDestroy(pThis); return VINF_SUCCESS; }
/** * Displays a verbose message. * * @param iLevel Minimum log level required to display this message. * @param pszFormat The message text. * @param ... Format arguments. */ void VBoxServiceVerbose(int iLevel, const char *pszFormat, ...) { if (iLevel <= g_cVerbosity) { #ifdef DEBUG int rc = RTCritSectEnter(&g_csLog); if (RT_SUCCESS(rc)) { #endif va_list args; va_start(args, pszFormat); char *psz = NULL; RTStrAPrintfV(&psz, pszFormat, args); va_end(args); AssertPtr(psz); LogRel(("%s", psz)); RTStrFree(psz); #ifdef DEBUG RTCritSectLeave(&g_csLog); } #endif } }
/** * Destroys an module after the reference count has reached zero. * * @param pDbgMod The module instance. */ static void rtDbgModDestroy(PRTDBGMODINT pDbgMod) { /* * Close the debug info interpreter first, then the image interpret. */ RTCritSectEnter(&pDbgMod->CritSect); /* paranoia */ if (pDbgMod->pDbgVt) { pDbgMod->pDbgVt->pfnClose(pDbgMod); pDbgMod->pDbgVt = NULL; pDbgMod->pvDbgPriv = NULL; } if (pDbgMod->pImgVt) { pDbgMod->pImgVt->pfnClose(pDbgMod); pDbgMod->pImgVt = NULL; pDbgMod->pvImgPriv = NULL; } /* * Free the resources. */ ASMAtomicWriteU32(&pDbgMod->u32Magic, ~RTDBGMOD_MAGIC); RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName); RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile); RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszDbgFile); RTCritSectLeave(&pDbgMod->CritSect); /* paranoia */ RTCritSectDelete(&pDbgMod->CritSect); RTMemFree(pDbgMod); }
RTDECL(int) RTLocalIpcServerCancel(RTLOCALIPCSERVER hServer) { /* * Validate input. */ PRTLOCALIPCSERVERINT pThis = (PRTLOCALIPCSERVERINT)hServer; AssertPtrReturn(pThis, VERR_INVALID_HANDLE); AssertReturn(pThis->u32Magic == RTLOCALIPCSERVER_MAGIC, VERR_INVALID_MAGIC); /* * Enter the critical section, then set the cancellation flag * and signal the event (to wake up anyone in/at WaitForSingleObject). */ int rc = RTCritSectEnter(&pThis->CritSect); if (RT_SUCCESS(rc)) { ASMAtomicUoWriteBool(&pThis->fCancelled, true); BOOL fRc = SetEvent(pThis->hEvent); AssertMsg(fRc, ("%d\n", GetLastError())); NOREF(fRc); rc = RTCritSectLeave(&pThis->CritSect); } return rc; }
void GuestBase::unregisterEvent(GuestWaitEvent *pEvent) { AssertPtrReturnVoid(pEvent); int rc = RTCritSectEnter(&mWaitEventCritSect); if (RT_SUCCESS(rc)) { const std::list<VBoxEventType_T> lstTypes = pEvent->Types(); for (std::list<VBoxEventType_T>::const_iterator itEvents = lstTypes.begin(); itEvents != lstTypes.end(); itEvents++) { /** @todo Slow O(n) lookup. Optimize this. */ GuestWaitEvents::iterator itCurEvent = mWaitEvents[(*itEvents)].begin(); while (itCurEvent != mWaitEvents[(*itEvents)].end()) { if ((*itCurEvent) == pEvent) { itCurEvent = mWaitEvents[(*itEvents)].erase(itCurEvent); break; } else itCurEvent++; } } delete pEvent; int rc2 = RTCritSectLeave(&mWaitEventCritSect); if (RT_SUCCESS(rc)) rc = rc2; } }
/** * Internal deregistration helper. * * @returns VBox status code. * @param pUVM Pointer to the VM. * @param pszName The identifier of the info. * @param enmType The info owner type. */ static int dbgfR3InfoDeregister(PUVM pUVM, const char *pszName, DBGFINFOTYPE enmType) { /* * Validate input. */ AssertPtrReturn(pszName, VERR_INVALID_POINTER); /* * Find the info handler. */ size_t cchName = strlen(pszName); int rc = RTCritSectEnter(&pUVM->dbgf.s.InfoCritSect); AssertRC(rc); rc = VERR_FILE_NOT_FOUND; PDBGFINFO pPrev = NULL; PDBGFINFO pInfo = pUVM->dbgf.s.pInfoFirst; for (; pInfo; pPrev = pInfo, pInfo = pInfo->pNext) if ( pInfo->cchName == cchName && !strcmp(pInfo->szName, pszName) && pInfo->enmType == enmType) { if (pPrev) pPrev->pNext = pInfo->pNext; else pUVM->dbgf.s.pInfoFirst = pInfo->pNext; MMR3HeapFree(pInfo); rc = VINF_SUCCESS; break; } int rc2 = RTCritSectLeave(&pUVM->dbgf.s.InfoCritSect); AssertRC(rc2); AssertRC(rc); LogFlow(("dbgfR3InfoDeregister: returns %Rrc\n", rc)); return rc; }
/** * Client mode connection thread. * * @returns iprt status code. * @param hSelf Thread handle. Use to sleep on. The main thread will * signal it to speed up thread shutdown. * @param pvUser Ignored. */ static DECLCALLBACK(int) txsTcpClientConnectThread(RTTHREAD hSelf, void *pvUser) { for (;;) { /* Stop? */ RTCritSectEnter(&g_TcpCritSect); bool fStop = g_fTcpStopConnecting; RTCritSectLeave(&g_TcpCritSect); if (fStop) return VINF_SUCCESS; /* Try connect. */ /** @todo make cancelable! */ RTSOCKET hTcpClient; Log2(("Calling RTTcpClientConnect(%s, %u,)...\n", g_szTcpConnectAddr, g_uTcpConnectPort)); int rc = RTTcpClientConnectEx(g_szTcpConnectAddr, g_uTcpConnectPort, &hTcpClient, RT_SOCKETCONNECT_DEFAULT_WAIT, &g_pTcpConnectCancelCookie); Log(("txsTcpRecvPkt: RTTcpClientConnect -> %Rrc\n", rc)); if (RT_SUCCESS(rc)) { hTcpClient = txsTcpSetClient(hTcpClient, true /*fFromServer*/); RTTcpClientCloseEx(hTcpClient, true /* fGracefulShutdown*/); break; } if (txsTcpIsFatalClientConnectStatus(rc)) return rc; /* Delay a wee bit before retrying. */ RTThreadUserWait(hSelf, 1536); } return VINF_SUCCESS; }
/** * @callback_method_impl{FNDBGCCMD, The '.injecterror' command.} */ static DECLCALLBACK(int) pdmacEpFileErrorInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR pArgs, unsigned cArgs) { /* * Validate input. */ DBGC_CMDHLP_REQ_UVM_RET(pCmdHlp, pCmd, pUVM); DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, -1, cArgs == 3); DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, pArgs[0].enmType == DBGCVAR_TYPE_STRING); DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 1, pArgs[1].enmType == DBGCVAR_TYPE_STRING); DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 2, pArgs[2].enmType == DBGCVAR_TYPE_NUMBER); PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile; pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pUVM->pdm.s.apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_FILE]; /* Syntax is "read|write <filename> <status code>" */ bool fWrite; if (!RTStrCmp(pArgs[0].u.pszString, "read")) fWrite = false; else if (!RTStrCmp(pArgs[0].u.pszString, "write")) fWrite = true; else return DBGCCmdHlpFail(pCmdHlp, pCmd, "invalid transfer direction '%s'", pArgs[0].u.pszString); int32_t rcToInject = (int32_t)pArgs[2].u.u64Number; if ((uint64_t)rcToInject != pArgs[2].u.u64Number) return DBGCCmdHlpFail(pCmdHlp, pCmd, "The status code '%lld' is out of range", pArgs[0].u.u64Number); /* * Search for the matching endpoint. */ RTCritSectEnter(&pEpClassFile->Core.CritSect); PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpClassFile->Core.pEndpointsHead; while (pEpFile) { if (!RTStrCmp(pArgs[1].u.pszString, RTPathFilename(pEpFile->Core.pszUri))) break; pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpFile->Core.pNext; } if (pEpFile) { /* * Do the job. */ if (fWrite) ASMAtomicXchgS32(&pEpFile->rcReqWrite, rcToInject); else ASMAtomicXchgS32(&pEpFile->rcReqRead, rcToInject); DBGCCmdHlpPrintf(pCmdHlp, "Injected %Rrc into '%s' for %s\n", (int)rcToInject, pArgs[1].u.pszString, pArgs[0].u.pszString); } RTCritSectLeave(&pEpClassFile->Core.CritSect); if (!pEpFile) return DBGCCmdHlpFail(pCmdHlp, pCmd, "No file with name '%s' found", pArgs[1].u.pszString); return VINF_SUCCESS; }
/** * Closes the specified stream. * * @returns iprt status code. * @param pStream The stream to close. */ RTR3DECL(int) RTStrmClose(PRTSTREAM pStream) { if (!pStream) return VINF_SUCCESS; AssertReturn(RT_VALID_PTR(pStream) && pStream->u32Magic == RTSTREAM_MAGIC, VERR_INVALID_PARAMETER); if (!fclose(pStream->pFile)) { pStream->u32Magic = 0xdeaddead; pStream->pFile = NULL; #ifndef HAVE_FWRITE_UNLOCKED if (pStream->pCritSect) { RTCritSectEnter(pStream->pCritSect); RTCritSectLeave(pStream->pCritSect); RTCritSectDelete(pStream->pCritSect); RTMemFree(pStream->pCritSect); pStream->pCritSect = NULL; } #endif RTMemFree(pStream); return VINF_SUCCESS; } return RTErrConvertFromErrno(errno); }
/** * Delay inject callback. */ static DECLCALLBACK(int) pdmacEpFileDelayInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArgs, unsigned cArgs) { /* * Validate input. */ DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM); DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, -1, cArgs == 3); DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, pArgs[0].enmType == DBGCVAR_TYPE_STRING); DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 1, pArgs[1].enmType == DBGCVAR_TYPE_STRING); DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 2, pArgs[2].enmType == DBGCVAR_TYPE_NUMBER); PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile; pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pVM->pUVM->pdm.s.apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_FILE]; /* Syntax is "read|write <filename> <status code>" */ bool fWrite; if (!RTStrCmp(pArgs[0].u.pszString, "read")) fWrite = false; else if (!RTStrCmp(pArgs[0].u.pszString, "write")) fWrite = true; else return DBGCCmdHlpFail(pCmdHlp, pCmd, "invalid transfer direction '%s'", pArgs[0].u.pszString); uint32_t msDelay = (uint32_t)pArgs[2].u.u64Number; if ((uint64_t)msDelay != pArgs[2].u.u64Number) return DBGCCmdHlpFail(pCmdHlp, pCmd, "The delay '%lld' is out of range", pArgs[0].u.u64Number); /* * Search for the matching endpoint. */ RTCritSectEnter(&pEpClassFile->Core.CritSect); PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpClassFile->Core.pEndpointsHead; while (pEpFile) { if (!RTStrCmp(pArgs[1].u.pszString, RTPathFilename(pEpFile->Core.pszUri))) break; pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpFile->Core.pNext; } if (pEpFile) { bool fXchg = ASMAtomicCmpXchgU32(&pEpFile->msDelay, msDelay, 0); if (fXchg) DBGCCmdHlpPrintf(pCmdHlp, "Injected delay of %u ms into '%s' for %s\n", msDelay, pArgs[1].u.pszString, pArgs[0].u.pszString); else DBGCCmdHlpPrintf(pCmdHlp, "Another delay for '%s' is still active, ignoring\n", pArgs[1].u.pszString); } RTCritSectLeave(&pEpClassFile->Core.CritSect); if (!pEpFile) return DBGCCmdHlpFail(pCmdHlp, pCmd, "No file with name '%s' found", pArgs[1].u.pszString); return VINF_SUCCESS; }
/** * Process events pending on this event queue, and wait up to given timeout, if * nothing is available. * * Must be called on same thread this event queue was created on. * * @param cMsTimeout The timeout specified as milliseconds. Use * RT_INDEFINITE_WAIT to wait till an event is posted on the * queue. * * @returns VBox status code * @retval VINF_SUCCESS if one or more messages was processed. * @retval VERR_TIMEOUT if cMsTimeout expired. * @retval VERR_INVALID_CONTEXT if called on the wrong thread. * @retval VERR_INTERRUPTED if interruptEventQueueProcessing was called. * On Windows will also be returned when WM_QUIT is encountered. * On Darwin this may also be returned when the native queue is * stopped or destroyed/finished. * @retval VINF_INTERRUPTED if the native system call was interrupted by a * an asynchronous event delivery (signal) or just felt like returning * out of bounds. On darwin it will also be returned if the queue is * stopped. */ int EventQueue::processEventQueue(RTMSINTERVAL cMsTimeout) { size_t cNumEvents; int rc = RTCritSectEnter(&mCritSect); if (RT_SUCCESS(rc)) { if (mUserCnt == 0) /* No concurrent access allowed. */ { mUserCnt++; cNumEvents = mEvents.size(); if (!cNumEvents) { int rc2 = RTCritSectLeave(&mCritSect); AssertRC(rc2); rc = RTSemEventWaitNoResume(mSemEvent, cMsTimeout); rc2 = RTCritSectEnter(&mCritSect); AssertRC(rc2); if (RT_SUCCESS(rc)) { if (mShutdown) rc = VERR_INTERRUPTED; cNumEvents = mEvents.size(); } } if (RT_SUCCESS(rc)) rc = processPendingEvents(cNumEvents); Assert(mUserCnt); mUserCnt--; } else rc = VERR_WRONG_ORDER; int rc2 = RTCritSectLeave(&mCritSect); if (RT_SUCCESS(rc)) rc = rc2; } Assert(rc != VERR_TIMEOUT || cMsTimeout != RT_INDEFINITE_WAIT); return rc; }
/*virtual*/ void WriteLockHandle::lockWrite(LOCKVAL_SRC_POS_DECL) { #ifdef VBOX_WITH_MAIN_LOCK_VALIDATION RTCritSectEnterDebug(&m->sem, (uintptr_t)ASMReturnAddress(), RT_SRC_POS_ARGS); #else RTCritSectEnter(&m->sem); #endif }
/** * Grows the cache. * * @returns IPRT status code. * @param pThis The memory cache instance. */ static int rtMemCacheGrow(RTMEMCACHEINT *pThis) { /* * Enter the critical section here to avoid allocation races leading to * wasted memory (++) and make it easier to link in the new page. */ RTCritSectEnter(&pThis->CritSect); int rc = VINF_SUCCESS; if (pThis->cFree < 0) { /* * Allocate and initialize the new page. * * We put the constructor bitmap at the lower end right after cFree. * We then push the object array to the end of the page and place the * allocation bitmap below it. The hope is to increase the chance that * the allocation bitmap is in a different cache line than cFree since * this increases performance markably when lots of threads are beating * on the cache. */ PRTMEMCACHEPAGE pPage = (PRTMEMCACHEPAGE)RTMemPageAlloc(PAGE_SIZE); if (pPage) { uint32_t const cObjects = RT_MIN(pThis->cPerPage, pThis->cMax - pThis->cTotal); ASMMemZeroPage(pPage); pPage->pCache = pThis; pPage->pNext = NULL; pPage->cFree = cObjects; pPage->cObjects = cObjects; uint8_t *pb = (uint8_t *)(pPage + 1); pb = RT_ALIGN_PT(pb, 8, uint8_t *); pPage->pbmCtor = pb; pb = (uint8_t *)pPage + PAGE_SIZE - pThis->cbObject * cObjects; pPage->pbObjects = pb; Assert(RT_ALIGN_P(pb, pThis->cbAlignment) == pb); pb -= pThis->cBits / 8; pb = (uint8_t *)((uintptr_t)pb & ~(uintptr_t)7); pPage->pbmAlloc = pb; Assert((uintptr_t)pPage->pbmCtor + pThis->cBits / 8 <= (uintptr_t)pPage->pbmAlloc); /* Mark the bitmap padding and any unused objects as allocated. */ for (uint32_t iBit = cObjects; iBit < pThis->cBits; iBit++) ASMBitSet(pPage->pbmAlloc, iBit); /* Make it the hint. */ ASMAtomicWritePtr(&pThis->pPageHint, pPage); /* Link the page in at the end of the list. */ ASMAtomicWritePtr(pThis->ppPageNext, pPage); pThis->ppPageNext = &pPage->pNext; /* Add it to the page counts. */ ASMAtomicAddS32(&pThis->cFree, cObjects); ASMAtomicAddU32(&pThis->cTotal, cObjects); } else
static void pdmNsBwGroupLink(PPDMNSBWGROUP pBwGroup) { PPDMNETSHAPER pShaper = pBwGroup->pShaper; int rc = RTCritSectEnter(&pShaper->cs); AssertRC(rc); pBwGroup->pNext = pShaper->pBwGroupsHead; pShaper->pBwGroupsHead = pBwGroup; rc = RTCritSectLeave(&pShaper->cs); AssertRC(rc); }
STDMETHODIMP HostDnsService::COMGETTER(DomainName)(BSTR *aDomainName) { RTCritSectEnter(&m_hCritSect); m_DomainName.cloneTo(aDomainName); RTCritSectLeave(&m_hCritSect); return S_OK; }
static void pdmNsFilterLink(PPDMNSFILTER pFilter) { PPDMNSBWGROUP pBwGroup = pFilter->pBwGroupR3; int rc = RTCritSectEnter(&pBwGroup->cs); AssertRC(rc); pFilter->pNext = pBwGroup->pFiltersHead; pBwGroup->pFiltersHead = pFilter; rc = RTCritSectLeave(&pBwGroup->cs); AssertRC(rc); }