Esempio n. 1
0
/**
 * 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;
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
/**
 * 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;
}
Esempio n. 5
0
/**
 * 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;
}
Esempio n. 6
0
/**
 * 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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
/**
 * 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);
}
Esempio n. 9
0
/**
 * 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"));
}
Esempio n. 11
0
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);
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
/**
 * 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;
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
/**
 * 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
    }
}
Esempio n. 17
0
/**
 * 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);
}
Esempio n. 18
0
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;
}
Esempio n. 19
0
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;
    }
}
Esempio n. 20
0
/**
 * 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;
}
Esempio n. 22
0
/**
 * @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;
}
Esempio n. 23
0
/**
 * 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;
}
Esempio n. 25
0
/**
 * 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;
}
Esempio n. 26
0
/*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
}
Esempio n. 27
0
/**
 * 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
Esempio n. 28
0
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;
}
Esempio n. 30
0
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);
}