Пример #1
0
int GuestWaitEventBase::Wait(RTMSINTERVAL uTimeoutMS)
{
    int rc = VINF_SUCCESS;

    if (ASMAtomicReadBool(&mfAborted))
        rc = VERR_CANCELLED;

    if (RT_SUCCESS(rc))
    {
        AssertReturn(mEventSem != NIL_RTSEMEVENT, VERR_CANCELLED);

        RTMSINTERVAL msInterval = uTimeoutMS;
        if (!uTimeoutMS)
            msInterval = RT_INDEFINITE_WAIT;
        rc = RTSemEventWait(mEventSem, msInterval);
        if (ASMAtomicReadBool(&mfAborted))
            rc = VERR_CANCELLED;
        if (RT_SUCCESS(rc))
        {
            /* If waiting succeeded, return the overall
             * result code. */
            rc = mRc;
        }
    }

    return rc;
}
Пример #2
0
void vboxNetAdpOsDestroy(PVBOXNETADP pThis)
{
    u_int32_t i;
    /* Bring down the interface */
    int rc = VINF_SUCCESS;
    errno_t err;

    AssertPtr(pThis->u.s.pIface);
    Assert(pThis->u.s.hEvtDetached != NIL_RTSEMEVENT);

    err = ifnet_set_flags(pThis->u.s.pIface, 0, IFF_UP | IFF_RUNNING);
    if (err)
        Log(("vboxNetAdpDarwinUnregisterDevice: Failed to bring down interface "
             "(err=%d).\n", err));
    /* Detach all protocols. */
    for (i = 0; i < VBOXNETADP_MAX_FAMILIES; i++)
        if (pThis->u.s.aAttachedFamilies[i])
            ifnet_detach_protocol(pThis->u.s.pIface, pThis->u.s.aAttachedFamilies[i]);
    err = ifnet_detach(pThis->u.s.pIface);
    if (err)
        Log(("vboxNetAdpDarwinUnregisterDevice: Failed to detach interface "
             "(err=%d).\n", err));
    Log2(("vboxNetAdpDarwinUnregisterDevice: Waiting for 'detached' event...\n"));
    /* Wait until we get a signal from detach callback. */
    rc = RTSemEventWait(pThis->u.s.hEvtDetached, VBOXNETADP_DETACH_TIMEOUT);
    if (rc == VERR_TIMEOUT)
        LogRel(("VBoxAdpDrv: Failed to detach interface %s%d\n.",
                VBOXNETADP_NAME, pThis->iUnit));
    err = ifnet_release(pThis->u.s.pIface);
    if (err)
        Log(("vboxNetAdpUnregisterDevice: Failed to release interface (err=%d).\n", err));

    RTSemEventDestroy(pThis->u.s.hEvtDetached);
    pThis->u.s.hEvtDetached = NIL_RTSEMEVENT;
}
Пример #3
0
/**
 * @copydoc INTNETTRUNKIFPORT::pfnWaitForIdle
 */
static DECLCALLBACK(int) vboxNetAdpPortWaitForIdle(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies)
{
    int rc;
    PVBOXNETADP pThis = IFPORT_2_VBOXNETADP(pIfPort);

    /*
     * Input validation.
     */
    AssertPtr(pThis);
    Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION);
    AssertReturn(vboxNetAdpGetStateWithLock(pThis) >= kVBoxNetAdpState_Connected, VERR_INVALID_STATE);

    /*
     * Go to sleep on the semaphore after checking the busy count.
     */
    vboxNetAdpRetain(pThis);

    rc = VINF_SUCCESS;
    while (pThis->cBusy && RT_SUCCESS(rc))
        rc = RTSemEventWait(pThis->hEventIdle, cMillies); /** @todo make interruptible? */

    vboxNetAdpRelease(pThis);

    return rc;
}
Пример #4
0
/**
 * Thread checking for expired requests.
 *
 * @returns IPRT status code.
 * @param   pThread    Thread handle.
 * @param   pvUser     Opaque user data.
 */
static int drvdiskIntIoReqExpiredCheck(RTTHREAD pThread, void *pvUser)
{
    PDRVDISKINTEGRITY pThis = (PDRVDISKINTEGRITY)pvUser;

    while (pThis->fRunning)
    {
        int rc = RTSemEventWait(pThis->SemEvent, pThis->uCheckIntervalMs);

        if (!pThis->fRunning)
            break;

        Assert(rc == VERR_TIMEOUT);

        /* Get current timestamp for comparison. */
        uint64_t tsCurr = RTTimeSystemMilliTS();

        /* Go through the array and check for expired requests. */
        for (unsigned i = 0; i < RT_ELEMENTS(pThis->apReqActive); i++)
        {
            PDRVDISKAIOREQACTIVE pReqActive = &pThis->apReqActive[i];
            PDRVDISKAIOREQ pIoReq = ASMAtomicReadPtrT(&pReqActive->pIoReq, PDRVDISKAIOREQ);

            if (   pIoReq
                && (tsCurr > pReqActive->tsStart)
                && (tsCurr - pReqActive->tsStart) >= pThis->uExpireIntervalMs)
            {
                RTMsgError("Request %#p expired (active for %llu ms already)\n",
                           pIoReq, tsCurr - pReqActive->tsStart);
                RTAssertDebugBreak();
            }
        }
    }

    return VINF_SUCCESS;
}
Пример #5
0
/**
 * Default VMR3Wait() worker.
 *
 * @returns VBox status code.
 * @param   pUVMCPU            Pointer to the user mode VMCPU structure.
 */
static DECLCALLBACK(int) vmR3DefaultWait(PUVMCPU pUVCpu)
{
    ASMAtomicWriteBool(&pUVCpu->vm.s.fWait, true);

    PVM    pVM   = pUVCpu->pVM;
    PVMCPU pVCpu = pUVCpu->pVCpu;
    int    rc    = VINF_SUCCESS;
    for (;;)
    {
        /*
         * Check Relevant FFs.
         */
        if (    VM_FF_ISPENDING(pVM, VM_FF_EXTERNAL_SUSPENDED_MASK)
            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_EXTERNAL_SUSPENDED_MASK))
            break;

        /*
         * Wait for a while. Someone will wake us up or interrupt the call if
         * anything needs our attention.
         */
        rc = RTSemEventWait(pUVCpu->vm.s.EventSemWait, 1000);
        if (rc == VERR_TIMEOUT)
            rc = VINF_SUCCESS;
        else if (RT_FAILURE(rc))
        {
            rc = vmR3FatalWaitError(pUVCpu, "RTSemEventWait->%Rrc", rc);
            break;
        }
    }

    ASMAtomicUoWriteBool(&pUVCpu->vm.s.fWait, false);
    return rc;
}
Пример #6
0
RTDECL(int) RTReqWait(PRTREQ hReq, RTMSINTERVAL cMillies)
{
    LogFlow(("RTReqWait: hReq=%p cMillies=%d\n", hReq, cMillies));

    /*
     * Verify the supplied package.
     */
    PRTREQINT pReq = hReq;
    AssertPtrReturn(pReq, VERR_INVALID_HANDLE);
    AssertReturn(pReq->u32Magic == RTREQ_MAGIC, VERR_INVALID_HANDLE);
    AssertMsgReturn(   pReq->enmState != RTREQSTATE_QUEUED
                    || pReq->enmState != RTREQSTATE_PROCESSING
                    || pReq->enmState != RTREQSTATE_COMPLETED,
                    ("Invalid state %d\n", pReq->enmState),
                    VERR_RT_REQUEST_STATE);
    AssertMsgReturn(pReq->uOwner.hQueue && pReq->EventSem != NIL_RTSEMEVENT,
                    ("Invalid request package! Anyone cooking their own packages???\n"),
                    VERR_RT_REQUEST_INVALID_PACKAGE);
    AssertMsgReturn(pReq->enmType > RTREQTYPE_INVALID && pReq->enmType < RTREQTYPE_MAX,
                    ("Invalid package type %d valid range %d-%d inclusively. This was verified on alloc too...\n",
                     pReq->enmType, RTREQTYPE_INVALID + 1, RTREQTYPE_MAX - 1),
                    VERR_RT_REQUEST_INVALID_TYPE);

    /*
     * Wait on the package.
     */
    int rc;
    if (cMillies != RT_INDEFINITE_WAIT)
        rc = RTSemEventWait(pReq->EventSem, cMillies);
    else
    {
        do
        {
            rc = RTSemEventWait(pReq->EventSem, RT_INDEFINITE_WAIT);
            Assert(rc != VERR_TIMEOUT);
        } while (pReq->enmState != RTREQSTATE_COMPLETED);
    }
    if (rc == VINF_SUCCESS)
        ASMAtomicXchgSize(&pReq->fEventSemClear, true);
    if (pReq->enmState == RTREQSTATE_COMPLETED)
        rc = VINF_SUCCESS;
    LogFlow(("RTReqWait: returns %Rrc\n", rc));
    Assert(rc != VERR_INTERRUPTED);
    Assert(pReq->cRefs >= 1);
    return rc;
}
Пример #7
0
/**
 * Re-initializes a request when it's being recycled.
 *
 * @returns IRPT status code, the request is freed on failure.
 * @param   pReq                The request.
 * @param   enmType             The request type.
 */
DECLHIDDEN(int) rtReqReInit(PRTREQINT pReq, RTREQTYPE enmType)
{
    Assert(pReq->u32Magic == RTREQ_MAGIC);
    Assert(pReq->enmType  == RTREQTYPE_INVALID);
    Assert(pReq->enmState == RTREQSTATE_FREE);
    Assert(pReq->cRefs    == 0);

    /*
     * Make sure the event sem is not signaled.
     */
    if (!pReq->fEventSemClear)
    {
        int rc = RTSemEventWait(pReq->EventSem, 0);
        if (rc != VINF_SUCCESS && rc != VERR_TIMEOUT)
        {
            /*
             * This shall not happen, but if it does we'll just destroy
             * the semaphore and create a new one.
             */
            AssertMsgFailed(("rc=%Rrc from RTSemEventWait(%#x).\n", rc, pReq->EventSem));
            RTSemEventDestroy(pReq->EventSem);
            rc = RTSemEventCreate(&pReq->EventSem);
            if (RT_FAILURE(rc))
            {
                AssertRC(rc);
                pReq->EventSem = NIL_RTSEMEVENT;
                rtReqFreeIt(pReq);
                return rc;
            }
        }
        pReq->fEventSemClear = true;
    }
    else
        Assert(RTSemEventWait(pReq->EventSem, 0) == VERR_TIMEOUT);

    /*
     * Initialize the packet and return it.
     */
    ASMAtomicWriteNullPtr(&pReq->pNext);
    pReq->iStatusX = VERR_RT_REQUEST_STATUS_STILL_PENDING;
    pReq->enmState = RTREQSTATE_ALLOCATED;
    pReq->fFlags   = RTREQFLAGS_IPRT_STATUS;
    pReq->enmType  = enmType;
    pReq->cRefs    = 1;
    return VINF_SUCCESS;
}
int GuestDnDResponse::waitForGuestResponse(RTMSINTERVAL msTimeout /*= 500 */) const
{
    int rc = RTSemEventWait(m_EventSem, msTimeout);
#ifdef DEBUG_andy
    LogFlowFunc(("msTimeout=%RU32, rc=%Rrc\n", msTimeout, rc));
#endif
    return rc;
}
Пример #9
0
/**
 * I/O thread for the memory backend.
 *
 * @returns IPRT status code.
 *
 * @param hThread    The thread handle.
 * @param pvUser     Opaque user data.
 */
static int vdIoBackendMemThread(RTTHREAD hThread, void *pvUser)
{
    PVDIOBACKENDMEM pIoBackend = (PVDIOBACKENDMEM)pvUser;

    while (pIoBackend->fRunning)
    {
        int rc = RTSemEventWait(pIoBackend->EventSem, RT_INDEFINITE_WAIT);
        if (RT_FAILURE(rc) || !pIoBackend->fRunning)
            break;

        PVDIOBACKENDREQ pReq;
        PPVDIOBACKENDREQ ppReq;
        size_t cbData;
        uint32_t cReqsWaiting = ASMAtomicXchgU32(&pIoBackend->cReqsWaiting, 0);

        while (cReqsWaiting)
        {
            int rcReq = VINF_SUCCESS;

            /* Do we have another request? */
            RTCircBufAcquireReadBlock(pIoBackend->pRequestRing, sizeof(PVDIOBACKENDREQ), (void **)&ppReq, &cbData);
            Assert(!ppReq || cbData == sizeof(PVDIOBACKENDREQ));
            RTCircBufReleaseReadBlock(pIoBackend->pRequestRing, cbData);

            pReq = *ppReq;
            cReqsWaiting--;

            LogFlowFunc(("Processing request\n"));
            switch (pReq->enmTxDir)
            {
                case VDIOTXDIR_READ:
                {
                    RTSGBUF SgBuf;
                    RTSgBufInit(&SgBuf, pReq->aSegs, pReq->cSegs);
                    rcReq = VDMemDiskRead(pReq->pMemDisk, pReq->off, pReq->cbTransfer, &SgBuf);
                    break;
                }
                case VDIOTXDIR_WRITE:
                {
                    RTSGBUF SgBuf;
                    RTSgBufInit(&SgBuf, pReq->aSegs, pReq->cSegs);
                    rcReq = VDMemDiskWrite(pReq->pMemDisk, pReq->off, pReq->cbTransfer, &SgBuf);
                    break;
                }
                case VDIOTXDIR_FLUSH:
                    break;
                default:
                    AssertMsgFailed(("Invalid TX direction!\n"));
            }

            /* Notify completion. */
            pReq->pfnComplete(pReq->pvUser, rcReq);
            RTMemFree(pReq);
        }
    }

    return VINF_SUCCESS;
}
Пример #10
0
HRESULT HostDnsServiceDarwin::start()
{
    int rc = RTThreadCreate(&g_DnsMonitoringThread, hostMonitoringRoutine,
                            this, 128 * _1K, RTTHREADTYPE_IO, 0, "dns-monitor");
    AssertRCReturn(rc, E_FAIL);

    RTSemEventWait(g_DnsInitEvent, RT_INDEFINITE_WAIT);

    return S_OK;
}
Пример #11
0
int VBoxDnDDropTarget::WaitForDrop(RTMSINTERVAL msTimeout)
{
    LogFlowFunc(("msTimeout=%RU32\n", msTimeout));

    int rc = RTSemEventWait(hEventDrop, msTimeout);
    if (RT_SUCCESS(rc))
        rc = mDroppedRc;

    LogFlowFuncLeaveRC(rc);
    return rc;
}
Пример #12
0
void HostDnsServiceDarwin::monitorThreadShutdown()
{
    ALock l(this);
    if (!m->m_fStop)
    {
        CFRunLoopSourceSignal(m->m_Stopper);
        CFRunLoopWakeUp(m->m_RunLoopRef);

        RTSemEventWait(m->m_evtStop, RT_INDEFINITE_WAIT);
    }
}
Пример #13
0
/** VM IPC mutex holder thread */
DECLCALLBACK(int) IPCMutexHolderThread (RTTHREAD Thread, void *pvUser)
{
    LogFlowFuncEnter();

    Assert (pvUser);
    void **data = (void **) pvUser;

    Utf8Str ipcId = (BSTR)data[0];
    RTSEMEVENT finishSem = (RTSEMEVENT)data[1];

    LogFlowFunc (("ipcId='%s', finishSem=%p\n", ipcId.raw(), finishSem));

    HMTX ipcMutex = NULLHANDLE;
    APIRET arc = ::DosOpenMutexSem ((PSZ) ipcId.raw(), &ipcMutex);
    AssertMsg (arc == NO_ERROR, ("cannot open IPC mutex, arc=%ld\n", arc));

    if (arc == NO_ERROR)
    {
        /* grab the mutex */
        LogFlowFunc (("grabbing IPC mutex...\n"));
        arc = ::DosRequestMutexSem (ipcMutex, SEM_IMMEDIATE_RETURN);
        AssertMsg (arc == NO_ERROR, ("cannot grab IPC mutex, arc=%ld\n", arc));
        if (arc == NO_ERROR)
        {
            /* store the answer */
            data[2] = (void*)true;
            /* signal we're done */
            int vrc = RTThreadUserSignal (Thread);
            AssertRC(vrc);

            /* wait until we're signaled to release the IPC mutex */
            LogFlowFunc (("waiting for termination signal..\n"));
            vrc = RTSemEventWait (finishSem, RT_INDEFINITE_WAIT);
            Assert (arc == ERROR_INTERRUPT || ERROR_TIMEOUT);

            /* release the IPC mutex */
            LogFlowFunc (("releasing IPC mutex...\n"));
            arc = ::DosReleaseMutexSem (ipcMutex);
            AssertMsg (arc == NO_ERROR, ("cannot release mutex, arc=%ld\n", arc));
        }

        ::DosCloseMutexSem (ipcMutex);
    }

    /* store the answer */
    data[1] = (void*)false;
    /* signal we're done */
    int vrc = RTThreadUserSignal (Thread);
    AssertRC(vrc);

    LogFlowFuncLeave();

    return 0;
}
Пример #14
0
/**
 * Block the main thread until the service shuts down.
 */
void VBoxServiceMainWait(void)
{
    int rc;

    VBoxServiceReportStatus(VBoxGuestFacilityStatus_Active);

#ifdef RT_OS_WINDOWS
    /*
     * Wait for the semaphore to be signalled.
     */
    VBoxServiceVerbose(1, "Waiting in main thread\n");
    rc = RTSemEventCreate(&g_hEvtWindowsService);
    AssertRC(rc);
    while (!ASMAtomicReadBool(&g_fWindowsServiceShutdown))
    {
        rc = RTSemEventWait(g_hEvtWindowsService, RT_INDEFINITE_WAIT);
        AssertRC(rc);
    }
    RTSemEventDestroy(g_hEvtWindowsService);
    g_hEvtWindowsService = NIL_RTSEMEVENT;
#else
    /*
     * Wait explicitly for a HUP, INT, QUIT, ABRT or TERM signal, blocking
     * all important signals.
     *
     * The annoying EINTR/ERESTART loop is for the benefit of Solaris where
     * sigwait returns when we receive a SIGCHLD.  Kind of makes sense since
     */
    sigset_t signalMask;
    sigemptyset(&signalMask);
    sigaddset(&signalMask, SIGHUP);
    sigaddset(&signalMask, SIGINT);
    sigaddset(&signalMask, SIGQUIT);
    sigaddset(&signalMask, SIGABRT);
    sigaddset(&signalMask, SIGTERM);
    pthread_sigmask(SIG_BLOCK, &signalMask, NULL);

    int iSignal;
    do
    {
        iSignal = -1;
        rc = sigwait(&signalMask, &iSignal);
    }
    while (   rc == EINTR
# ifdef ERESTART
              || rc == ERESTART
# endif
          );

    VBoxServiceVerbose(3, "VBoxServiceMainWait: Received signal %d (rc=%d)\n", iSignal, rc);
#endif /* !RT_OS_WINDOWS */
}
/**
 * Send a message to the async window thread and wait for a reply
 *
 * @returns VBox status code.
 * @param   pWindowThread   Thread handle
 * @param   WndRequestSem   Semaphore handle for waiting
 * @param   msg             Message id
 * @param   wParam          First parameter
 * @param   lParam          Second parameter
 */
int vmsvga3dSendThreadMessage(RTTHREAD pWindowThread, RTSEMEVENT WndRequestSem, UINT msg, WPARAM wParam, LPARAM lParam)
{
    int  rc;
    BOOL ret;

    ret = PostThreadMessage(RTThreadGetNative(pWindowThread), msg, wParam, lParam);
    AssertMsgReturn(ret, ("PostThreadMessage %x failed with %d\n", RTThreadGetNative(pWindowThread), GetLastError()), VERR_INTERNAL_ERROR);

    rc = RTSemEventWait(WndRequestSem, RT_INDEFINITE_WAIT);
    Assert(RT_SUCCESS(rc));

    return rc;
}
Пример #16
0
int GuestWaitEvent::Wait(RTMSINTERVAL uTimeoutMS)
{
    LogFlowThisFuncEnter();

    AssertReturn(mEventSem != NIL_RTSEMEVENT, VERR_CANCELLED);

    RTMSINTERVAL msInterval = uTimeoutMS;
    if (!uTimeoutMS)
        msInterval = RT_INDEFINITE_WAIT;
    int rc = RTSemEventWait(mEventSem, msInterval);

    LogFlowFuncLeaveRC(rc);
    return rc;
}
Пример #17
0
int vboxVhwaCommandSubmit(PVBOXMP_DEVEXT pDevExt, VBOXVHWACMD* pCmd)
{
#ifdef VBOXVHWA_WITH_SHGSMI
    const VBOXSHGSMIHEADER* pHdr = VBoxSHGSMICommandPrepSynch(&pDevExt->u.primary.hgsmiAdapterHeap, pCmd);
    Assert(pHdr);
    int rc = VERR_GENERAL_FAILURE;
    if (pHdr)
    {
        do
        {
            HGSMIOFFSET offCmd = VBoxSHGSMICommandOffset(&pDevExt->u.primary.hgsmiAdapterHeap, pHdr);
            Assert(offCmd != HGSMIOFFSET_VOID);
            if (offCmd != HGSMIOFFSET_VOID)
            {
                rc = vboxVhwaCommandSubmitHgsmi(pDevExt, offCmd);
                AssertRC(rc);
                if (RT_SUCCESS(rc))
                {
                    VBoxSHGSMICommandDoneSynch(&pDevExt->u.primary.hgsmiAdapterHeap, pHdr);
                    AssertRC(rc);
                    break;
                }
            }
            else
                rc = VERR_INVALID_PARAMETER;
            /* fail to submit, cancel it */
            VBoxSHGSMICommandCancelSynch(&pDevExt->u.primary.hgsmiAdapterHeap, pHdr);
        } while (0);
    }
    else
        rc = VERR_INVALID_PARAMETER;
    return rc;
#else
    RTSEMEVENT hEvent;
    int rc = RTSemEventCreate(&hEvent);
    AssertRC(rc);
    if (RT_SUCCESS(rc))
    {
        pCmd->Flags |= VBOXVHWACMD_FLAG_GH_ASYNCH_IRQ;
        vboxVhwaCommandSubmitAsynchByEvent(pDevExt, pCmd, hEvent);
        rc = RTSemEventWait(hEvent, RT_INDEFINITE_WAIT);
        AssertRC(rc);
        if (RT_SUCCESS(rc))
            RTSemEventDestroy(hEvent);
    }
    return rc;
#endif
}
Пример #18
0
/**
 * Wait on event semaphore for guest credential judgement result.
 */
int VMMDev::WaitCredentialsJudgement(uint32_t u32Timeout, uint32_t *pu32CredentialsFlags)
{
    if (u32Timeout == 0)
    {
        u32Timeout = 5000;
    }

    int rc = RTSemEventWait (mCredentialsEvent, u32Timeout);

    if (RT_SUCCESS(rc))
    {
        *pu32CredentialsFlags = mu32CredentialsFlags;
    }

    return rc;
}
Пример #19
0
int GuestCtrlEvent::Wait(ULONG uTimeoutMS)
{
    LogFlowFuncEnter();

    AssertReturn(hEventSem != NIL_RTSEMEVENT, VERR_CANCELLED);

    RTMSINTERVAL msInterval = uTimeoutMS;
    if (!uTimeoutMS)
        msInterval = RT_INDEFINITE_WAIT;
    int rc = RTSemEventWait(hEventSem, msInterval);
    if (RT_SUCCESS(rc))
        ASMAtomicWriteBool(&fCompleted, true);

    LogFlowFuncLeaveRC(rc);
    return rc;
}
/**
 * Send thread loop - pushes data down thru the driver chain.
 *
 * @returns 0 on success.
 * @param   ThreadSelf  Thread handle to this thread.
 * @param   pvUser      User argument.
 */
static DECLCALLBACK(int) drvCharSendLoop(RTTHREAD ThreadSelf, void *pvUser)
{
    PDRVCHAR pThis = (PDRVCHAR)pvUser;

    int rc = VINF_SUCCESS;
    while (!pThis->fShutdown)
    {
        RTMSINTERVAL cMillies = (rc == VERR_TIMEOUT) ? 50 : RT_INDEFINITE_WAIT;
        rc = RTSemEventWait(pThis->SendSem, cMillies);
        if (    RT_FAILURE(rc)
             && rc != VERR_TIMEOUT)
            break;

        /*
         * Write the character to the attached stream (if present).
         */
        if (    pThis->fShutdown
            ||  !pThis->pDrvStream)
            break;

        size_t cbProcessed = 1;
        uint8_t ch = pThis->u8SendByte;
        rc = pThis->pDrvStream->pfnWrite(pThis->pDrvStream, &ch, &cbProcessed);
        if (RT_SUCCESS(rc))
        {
            ASMAtomicXchgBool(&pThis->fSending, false);
            Assert(cbProcessed == 1);
        }
        else if (rc == VERR_TIMEOUT)
        {
            /* Normal case, just means that the stream didn't accept a new
             * character before the timeout elapsed. Just retry. */

            /* do not change the rc status here, otherwise the (rc == VERR_TIMEOUT) branch
             * in the wait above will never get executed */
            /* rc = VINF_SUCCESS; */
        }
        else
        {
            LogRel(("Write failed with %Rrc; skipping\n", rc));
            break;
        }
    }

    return VINF_SUCCESS;
}
Пример #21
0
/**
 * Wait for a (binary) semaphore.
 */
u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
{
    int rc;
    RTMSINTERVAL cMillies;
    uint64_t tsStart, tsEnd;

    tsStart = RTTimeMilliTS();
    if (timeout == 0)
        cMillies = RT_INDEFINITE_WAIT;
    else
        cMillies = timeout;
    rc = RTSemEventWait(sem, cMillies);
    if (rc == VERR_TIMEOUT)
        return SYS_ARCH_TIMEOUT;
    AssertRC(rc);
    tsEnd = RTTimeMilliTS();
    return tsEnd - tsStart;
}
Пример #22
0
static int pdmacFileAioMgrWaitForBlockingEvent(PPDMACEPFILEMGR pAioMgr, PDMACEPFILEAIOMGRBLOCKINGEVENT enmEvent)
{
    ASMAtomicWriteU32((volatile uint32_t *)&pAioMgr->enmBlockingEvent, enmEvent);
    Assert(!pAioMgr->fBlockingEventPending);
    ASMAtomicXchgBool(&pAioMgr->fBlockingEventPending, true);

    /* Wakeup the async I/O manager */
    pdmacFileAioMgrWakeup(pAioMgr);

    /* Wait for completion. */
    int rc = RTSemEventWait(pAioMgr->EventSemBlock, RT_INDEFINITE_WAIT);
    AssertRC(rc);

    ASMAtomicXchgBool(&pAioMgr->fBlockingEventPending, false);
    ASMAtomicWriteU32((volatile uint32_t *)&pAioMgr->enmBlockingEvent, PDMACEPFILEAIOMGRBLOCKINGEVENT_INVALID);

    return rc;
}
Пример #23
0
/**
 * Bootstrap VMR3Wait() worker.
 *
 * @returns VBox status code.
 * @param   pUVMCPU            Pointer to the user mode VMCPU structure.
 */
static DECLCALLBACK(int) vmR3BootstrapWait(PUVMCPU pUVCpu)
{
    PUVM pUVM = pUVCpu->pUVM;

    ASMAtomicWriteBool(&pUVCpu->vm.s.fWait, true);

    int rc = VINF_SUCCESS;
    for (;;)
    {
        /*
         * Check Relevant FFs.
         */
        if (pUVM->vm.s.pNormalReqs   || pUVM->vm.s.pPriorityReqs)   /* global requests pending? */
            break;
        if (pUVCpu->vm.s.pNormalReqs || pUVCpu->vm.s.pPriorityReqs) /* local requests pending? */
            break;

        if (    pUVCpu->pVM
            &&  (   VM_FF_ISPENDING(pUVCpu->pVM, VM_FF_EXTERNAL_SUSPENDED_MASK)
                 || VMCPU_FF_ISPENDING(VMMGetCpu(pUVCpu->pVM), VMCPU_FF_EXTERNAL_SUSPENDED_MASK)
                )
            )
            break;
        if (pUVM->vm.s.fTerminateEMT)
            break;

        /*
         * Wait for a while. Someone will wake us up or interrupt the call if
         * anything needs our attention.
         */
        rc = RTSemEventWait(pUVCpu->vm.s.EventSemWait, 1000);
        if (rc == VERR_TIMEOUT)
            rc = VINF_SUCCESS;
        else if (RT_FAILURE(rc))
        {
            rc = vmR3FatalWaitError(pUVCpu, "RTSemEventWait->%Rrc\n", rc);
            break;
        }
    }

    ASMAtomicUoWriteBool(&pUVCpu->vm.s.fWait, false);
    return rc;
}
Пример #24
0
DECLINLINE(int) shaWaitForManifestThreadFinished(PSHASTORAGEINTERNAL pInt)
{
//    RTPrintf("start\n");
    int rc = VINF_SUCCESS;
    for(;;)
    {
//        RTPrintf(" wait\n");
        uint32_t u32Status = ASMAtomicReadU32(&pInt->u32Status);
        if (!(   u32Status == STATUS_WRITE
              || u32Status == STATUS_WRITING
              || u32Status == STATUS_READ
              || u32Status == STATUS_READING))
            break;
        rc = RTSemEventWait(pInt->workFinishedEvent, 100);
    }
    if (rc == VERR_TIMEOUT)
        rc = VINF_SUCCESS;
    return rc;
}
Пример #25
0
int VbglR3SeamlessWaitEvent(VMMDevSeamlessMode *pMode)
{
    static bool active = false;

    int rc = VINF_SUCCESS;
    if (!active)
    {
        active = true;
        *pMode = VMMDev_Seamless_Visible_Region;
    }
    else
    {
        rc = RTSemEventWait(eventSem, RT_INDEFINITE_WAIT);
        if (RT_SUCCESS(rc))
        {
            rc = VERR_INTERRUPTED;
        }
    }
    return true;
}
VBoxDbgConsole::backInput(PDBGCBACK pBack, uint32_t cMillies)
{
    VBoxDbgConsole *pThis = VBOXDBGCONSOLE_FROM_DBGCBACK(pBack);
    pThis->lock();

    bool fRc = true;
    if (!pThis->m_cbInputBuf)
    {
        /*
         * Wait outside the lock for the requested time, then check again.
         */
        pThis->unlock();
        RTSemEventWait(pThis->m_EventSem, cMillies);
        pThis->lock();
        fRc = pThis->m_cbInputBuf
           || ASMAtomicUoReadBool(&pThis->m_fTerminate);
    }

    pThis->unlock();
    return fRc;
}
Пример #27
0
/**
 * Grab the pointer to this thread's timeouts from TLS.
 */
struct sys_timeouts *sys_arch_timeouts(void)
{
    unsigned i;
#if SYS_LIGHTWEIGHT_PROT
    SYS_ARCH_DECL_PROTECT(old_level);
#endif
    RTTHREAD myself;
    struct sys_timeouts *to = NULL;

    myself = RTThreadSelf();
#if SYS_LIGHTWEIGHT_PROT
    SYS_ARCH_PROTECT(old_level);
#else
    RTSemEventWait(g_ThreadSem, RT_INDEFINITE_WAIT);
#endif
    for (i = 0; i < g_cThreads; i++)
    {
        if (g_aTLS[i].tid == myself)
        {
            to = &g_aTLS[i].timeouts;
            break;
        }
    }
    /* Auto-adopt new threads which use lwIP as they pop up. */
    if (!to)
    {
        unsigned id;
        id = g_cThreads;
        g_cThreads++;
        Assert(g_cThreads <= THREADS_MAX);
        g_aTLS[id].tid = myself;
        to = &g_aTLS[id].timeouts;
    }
#if SYS_LIGHTWEIGHT_PROT
    SYS_ARCH_UNPROTECT(old_level);
#else
    RTSemEventSignal(g_ThreadSem);
#endif
    return to;
}
RTDECL(int) RTFileAioReqCancel(RTFILEAIOREQ hReq)
{
    PRTFILEAIOREQINTERNAL pReqInt = hReq;
    RTFILEAIOREQ_VALID_RETURN(pReqInt);
    RTFILEAIOREQ_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_NOT_SUBMITTED);

    ASMAtomicXchgBool(&pReqInt->fCanceled, true);

    int rcPosix = aio_cancel(pReqInt->AioCB.aio_fildes, &pReqInt->AioCB);

    if (rcPosix == AIO_CANCELED)
    {
        PRTFILEAIOCTXINTERNAL pCtxInt = pReqInt->pCtxInt;
        /*
         * Notify the waiting thread that the request was canceled.
         */
        AssertMsg(VALID_PTR(pCtxInt),
                  ("Invalid state. Request was canceled but wasn't submitted\n"));

        Assert(!pCtxInt->pReqToCancel);
        ASMAtomicWritePtr(&pCtxInt->pReqToCancel, pReqInt);
        rtFileAioCtxWakeup(pCtxInt);

        /* Wait for acknowledge. */
        int rc = RTSemEventWait(pCtxInt->SemEventCancel, RT_INDEFINITE_WAIT);
        AssertRC(rc);

        ASMAtomicWriteNullPtr(&pCtxInt->pReqToCancel);
        pReqInt->Rc = VERR_FILE_AIO_CANCELED;
        RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED);
        return VINF_SUCCESS;
    }
    else if (rcPosix == AIO_ALLDONE)
        return VERR_FILE_AIO_COMPLETED;
    else if (rcPosix == AIO_NOTCANCELED)
        return VERR_FILE_AIO_IN_PROGRESS;
    else
        return RTErrConvertFromErrno(errno);
}
Пример #29
0
/**
 * Wait function for the pong thread.
 *
 * @returns iprt status code.
 *          Will not return VERR_INTERRUPTED.
 * @param   pPP         Pointer to the ping-pong structure to wait on.
 * @param   cMillies    Number of milliseconds to wait.
 */
RTDECL(int) RTSemPongWait(PRTPINGPONG pPP, RTMSINTERVAL cMillies)
{
    /*
     * Validate input
     */
    RTPINGPONGSPEAKER enmSpeaker;
    RTSEMPP_VALIDATE_RETURN(pPP);
    AssertMsgReturn(    enmSpeaker == RTPINGPONGSPEAKER_PING
                    ||  enmSpeaker == RTPINGPONGSPEAKER_PING_SIGNALED
                    ||  enmSpeaker == RTPINGPONGSPEAKER_PONG_SIGNALED,
                    ("Speaking out of turn! enmSpeaker=%d\n", enmSpeaker),
                    VERR_SEM_OUT_OF_TURN);

    /*
     * Wait.
     */
    int rc = RTSemEventWait(pPP->Pong, cMillies);
    if (RT_SUCCESS(rc))
        ASMAtomicWriteSize(&pPP->enmSpeaker, RTPINGPONGSPEAKER_PONG);
    Assert(rc != VERR_INTERRUPTED);
    return rc;
}
Пример #30
0
/**
 * Create new thread.
 */
sys_thread_t sys_thread_new(void (* thread)(void *arg), void *arg, int prio)
{
    int rc;
#if SYS_LIGHTWEIGHT_PROT
    SYS_ARCH_DECL_PROTECT(old_level);
#endif
    unsigned id;
    RTTHREAD tid;

#if SYS_LIGHTWEIGHT_PROT
    SYS_ARCH_PROTECT(old_level);
#else
    RTSemEventWait(g_ThreadSem, RT_INDEFINITE_WAIT);
#endif
    id = g_cThreads;
    g_cThreads++;
    Assert(g_cThreads <= THREADS_MAX);
    g_aTLS[id].thread = thread;
    g_aTLS[id].arg = arg;
    rc = RTThreadCreateF(&tid, sys_thread_adapter, &g_aTLS[id], 0,
                         RTTHREADTYPE_IO, 0, "lwIP%u", id);
    if (RT_FAILURE(rc))
    {
        g_cThreads--;
        tid = NIL_RTTHREAD;
    }
    else
        g_aTLS[id].tid = tid;
#if SYS_LIGHTWEIGHT_PROT
    SYS_ARCH_UNPROTECT(old_level);
#else
    RTSemEventSignal(g_ThreadSem);
#endif
    AssertRC(rc);
    return tid;
}