Ejemplo n.º 1
0
RTDECL(int) RTPoll(RTPOLLSET hPollSet, RTMSINTERVAL cMillies, uint32_t *pfEvents, uint32_t *pid)
{
    RTPOLLSETINTERNAL *pThis = hPollSet;
    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    AssertReturn(pThis->u32Magic == RTPOLLSET_MAGIC, VERR_INVALID_HANDLE);
    AssertPtrNull(pfEvents);
    AssertPtrNull(pid);

    /*
     * Set the busy flag and do the job.
     */
    AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true,  false), VERR_CONCURRENT_ACCESS);

    int rc;
    if (cMillies == RT_INDEFINITE_WAIT || cMillies == 0)
    {
        do rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);
        while (rc == VERR_INTERRUPTED);
    }
    else
    {
        uint64_t MsStart = RTTimeMilliTS();
        rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);
        while (RT_UNLIKELY(rc == VERR_INTERRUPTED))
        {
            if (RTTimeMilliTS() - MsStart >= cMillies)
            {
                rc = VERR_TIMEOUT;
                break;
            }
            rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);
        }
    }

    ASMAtomicWriteBool(&pThis->fBusy, false);

    return rc;
}
Ejemplo n.º 2
0
HRESULT ListenerRecord::dequeue(IEvent **aEvent,
                                LONG aTimeout,
                                AutoLockBase &aAlock)
{
    if (mActive)
        return VBOX_E_INVALID_OBJECT_STATE;

    // retain listener record
    RecordHolder<ListenerRecord> holder(this);

    ::RTCritSectEnter(&mcsQLock);

    mLastRead = RTTimeMilliTS();

    /*
     * If waiting both desired and necessary, then try grab the event
     * semaphore and mark it busy.  If it's NIL we've been shut down already.
     */
    if (aTimeout != 0 && mQueue.empty())
    {
        RTSEMEVENT hEvt = mQEvent;
        if (hEvt != NIL_RTSEMEVENT)
        {
            ASMAtomicIncS32(&mQEventBusyCnt);
            ::RTCritSectLeave(&mcsQLock);

            // release lock while waiting, listener will not go away due to above holder
            aAlock.release();

            ::RTSemEventWait(hEvt, aTimeout);
            ASMAtomicDecS32(&mQEventBusyCnt);

            // reacquire lock
            aAlock.acquire();
            ::RTCritSectEnter(&mcsQLock);
        }
    }

    if (mQueue.empty())
        *aEvent = NULL;
    else
    {
        mQueue.front().queryInterfaceTo(aEvent);
        mQueue.pop_front();
    }

    ::RTCritSectLeave(&mcsQLock);
    return S_OK;
}
int ConfigurationManager::commitLease4Client(Client& client)
{
    Lease l = client.lease();
    AssertReturn(l != Lease::NullLease, VERR_INTERNAL_ERROR);

    l.bindingPhase(false);
    const NetworkConfigEntity *pCfg = l.getConfig();

    AssertPtr(pCfg);
    l.setExpiration(pCfg->expirationPeriod());
    l.phaseStart(RTTimeMilliTS());

    saveToFile();

    return VINF_SUCCESS;
}
Ejemplo n.º 4
0
HRESULT ListenerRecord::dequeue (IEvent*       *aEvent,
                                 LONG          aTimeout,
                                 AutoLockBase& aAlock)
{
    if (mActive)
        return VBOX_E_INVALID_OBJECT_STATE;

    // retain listener record
    RecordHolder<ListenerRecord> holder(this);

    ::RTCritSectEnter(&mcsQLock);

    mLastRead = RTTimeMilliTS();

    if (mQueue.empty())    {
        ::RTCritSectLeave(&mcsQLock);
        // Speed up common case
        if (aTimeout == 0)
        {
            *aEvent = NULL;
            return S_OK;
        }
        // release lock while waiting, listener will not go away due to above holder
        aAlock.release();
        ::RTSemEventWait(mQEvent, aTimeout);
        // reacquire lock
        aAlock.acquire();
        ::RTCritSectEnter(&mcsQLock);
    }
    if (mQueue.empty())
    {
        *aEvent = NULL;
    }
    else
    {
        mQueue.front().queryInterfaceTo(aEvent);
        mQueue.pop_front();
    }
    ::RTCritSectLeave(&mcsQLock);
    return S_OK;
}
Ejemplo n.º 5
0
HRESULT ListenerRecord::enqueue(IEvent *aEvent)
{
    AssertMsg(!mActive, ("must be passive\n"));

    // put an event the queue
    ::RTCritSectEnter(&mcsQLock);

    // If there was no events reading from the listener for the long time,
    // and events keep coming, or queue is oversized we shall unregister this listener.
    uint64_t sinceRead = RTTimeMilliTS() - mLastRead;
    size_t queueSize = mQueue.size();
    if (queueSize > 1000 || (queueSize > 500 && sinceRead > 60 * 1000))
    {
        ::RTCritSectLeave(&mcsQLock);
        return E_ABORT;
    }


    RTSEMEVENT hEvt = mQEvent;
    if (queueSize != 0 && mQueue.back() == aEvent)
        /* if same event is being pushed multiple times - it's reusable event and
           we don't really need multiple instances of it in the queue */
        hEvt = NIL_RTSEMEVENT;
    else if (hEvt != NIL_RTSEMEVENT) /* don't bother queuing after shutdown */
    {
        mQueue.push_back(aEvent);
        ASMAtomicIncS32(&mQEventBusyCnt);
    }

    ::RTCritSectLeave(&mcsQLock);

    // notify waiters unless we've been shut down.
    if (hEvt != NIL_RTSEMEVENT)
    {
        ::RTSemEventSignal(hEvt);
        ASMAtomicDecS32(&mQEventBusyCnt);
    }

    return S_OK;
}
Ejemplo n.º 6
0
ListenerRecord::ListenerRecord(IEventListener*                  aListener,
                               com::SafeArray<VBoxEventType_T>& aInterested,
                               BOOL                             aActive,
                               EventSource*                     aOwner)
    :
    mActive(aActive),
    mOwner(aOwner),
    mRefCnt(0)
{
    mListener = aListener;
    EventMap* aEvMap = &aOwner->m->mEvMap;

    for (size_t i = 0; i < aInterested.size(); ++i)
    {
        VBoxEventType_T interested = aInterested[i];
        for (int j = FirstEvent; j < LastEvent; j++)
        {
            VBoxEventType_T candidate = (VBoxEventType_T)j;
            if (implies(interested, candidate))
            {
                (*aEvMap)[j - FirstEvent].add(this);
            }
        }
    }

    if (!mActive)
    {
        ::RTCritSectInit(&mcsQLock);
        ::RTSemEventCreate (&mQEvent);
        mLastRead = RTTimeMilliTS();
    }
    else
    {
        mQEvent =NIL_RTSEMEVENT;
        RT_ZERO(mcsQLock);
        mLastRead = 0;
    }
}
Ejemplo n.º 7
0
void
renderspu_SystemSwapBuffers(WindowInfo *window, GLint flags)
{
    CRASSERT(window);
    CRASSERT(window->window);

    ContextInfo *context = renderspuGetWindowContext(window);

    if(!context)
        crError("Render SPU (renderspu_SystemSwapBuffers): SwapBuffers got a null context from the window");

    RTSemFastMutexRequest(render_spu.syncMutex);
//    DEBUG_MSG_POETZSCH (("Swapped %d context %x visible: %d\n", window->BltInfo.Base.id, context->context, IsWindowVisible (window->window)));
    if (context->visual &&
        context->visual->visAttribs & CR_DOUBLE_BIT)
        render_spu.ws.aglSwapBuffers(context->context);
    else
        glFlush();
    RTSemFastMutexRelease(render_spu.syncMutex);

    /* This method seems called very often. To prevent the dock using all free
     * resources we update the dock only two times per second. */
    uint64_t curTS = RTTimeMilliTS();
    if ((curTS - render_spu.uiDockUpdateTS) > 500)
    {
        OSStatus status = noErr;
        /* Send a event to the main thread, cause some function of Carbon aren't
         * thread safe */
        EventRef evt;
        status = CreateEvent(NULL, kEventClassVBox, kEventVBoxUpdateDock, 0, kEventAttributeNone, &evt);
        CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemSwapBuffers): CreateEvent Failed");
        status = PostEventToQueue(GetMainEventQueue(), evt, kEventPriorityStandard);
        CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemSwapBuffers): PostEventToQueue Failed");

        render_spu.uiDockUpdateTS = curTS;
    }
}
/**
 * The client is requesting an offer.
 *
 * @returns true.
 *
 * @param   pDhcpMsg    The message.
 * @param   cb          The message size.
 */
bool NetworkManager::handleDhcpReqDiscover(PCRTNETBOOTP pDhcpMsg, size_t cb)
{
    RawOption opt;
    RT_ZERO(opt);

    /* 1. Find client */
    ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
    Client client = confManager->getClientByDhcpPacket(pDhcpMsg, cb);

    /* 2. Find/Bind lease for client */
    Lease lease = confManager->allocateLease4Client(client, pDhcpMsg, cb);
    AssertReturn(lease != Lease::NullLease, VINF_SUCCESS);

    int rc = ConfigurationManager::extractRequestList(pDhcpMsg, cb, opt);

    /* 3. Send of offer */

    lease.bindingPhase(true);
    lease.phaseStart(RTTimeMilliTS());
    lease.setExpiration(300); /* 3 min. */
    offer4Client(client, pDhcpMsg->bp_xid, opt.au8RawOpt, opt.cbRawOpt);

    return VINF_SUCCESS;
}
Ejemplo n.º 9
0
RTDECL(int) RTLocalIpcSessionWaitForData(RTLOCALIPCSESSION hSession, uint32_t cMillies)
{
    PRTLOCALIPCSESSIONINT pThis = (PRTLOCALIPCSESSIONINT)hSession;
    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    AssertReturn(pThis->u32Magic == RTLOCALIPCSESSION_MAGIC, VERR_INVALID_HANDLE);

    uint64_t const StartMsTS = RTTimeMilliTS();

    int rc = RTCritSectEnter(&pThis->CritSect);
    if (RT_FAILURE(rc))
        return rc;
    for (unsigned iLoop = 0;; iLoop++)
    {
        HANDLE hWait = INVALID_HANDLE_VALUE;

        if (pThis->fIOPending)
            hWait = pThis->OverlappedIO.hEvent;
        else
        {
            /* Peek at the pipe buffer and see how many bytes it contains. */
            DWORD cbAvailable;
            BOOL fRc = PeekNamedPipe(pThis->hNmPipe, NULL, 0, NULL, &cbAvailable, NULL);
            if (   fRc
                && cbAvailable)
            {
                rc = VINF_SUCCESS;
                break;
            }
            else if (!fRc)
            {
                rc = RTErrConvertFromWin32(GetLastError());
                break;
            }

            /* Start a zero byte read operation that we can wait on. */
            if (cMillies == 0)
            {
                rc = VERR_TIMEOUT;
                break;
            }
            AssertBreakStmt(pThis->cRefs == 1, rc = VERR_WRONG_ORDER);
            fRc = ResetEvent(pThis->OverlappedIO.hEvent); Assert(fRc == TRUE);
            DWORD cbRead = 0;
            if (ReadFile(pThis->hNmPipe, pThis->abBuf, 0, &cbRead, &pThis->OverlappedIO))
            {
                rc = VINF_SUCCESS;
                if (iLoop > 10)
                    RTThreadYield();
            }
            else if (GetLastError() == ERROR_IO_PENDING)
            {
                pThis->cRefs++;
                pThis->fIOPending = true;
                pThis->fZeroByteRead = true;
                hWait = pThis->OverlappedIO.hEvent;
            }
            else
                rc = RTErrConvertFromWin32(GetLastError());
        }

        if (RT_FAILURE(rc))
            break;

        /*
         * Check for timeout.
         */
        DWORD cMsMaxWait = INFINITE;
        if (   cMillies != RT_INDEFINITE_WAIT
            && (   hWait != INVALID_HANDLE_VALUE
                || iLoop > 10)
           )
        {
            uint64_t cElapsed = RTTimeMilliTS() - StartMsTS;
            if (cElapsed >= cMillies)
            {
                rc = VERR_TIMEOUT;
                break;
            }
            cMsMaxWait = cMillies - (uint32_t)cElapsed;
        }

        /*
         * Wait.
         */
        if (hWait != INVALID_HANDLE_VALUE)
        {
            RTCritSectLeave(&pThis->CritSect);

            DWORD dwRc = WaitForSingleObject(hWait, cMsMaxWait);
            if (dwRc == WAIT_OBJECT_0)
                rc = VINF_SUCCESS;
            else if (dwRc == WAIT_TIMEOUT)
                rc = VERR_TIMEOUT;
            else if (dwRc == WAIT_ABANDONED)
                rc = VERR_INVALID_HANDLE;
            else
                rc = RTErrConvertFromWin32(GetLastError());

            if (   RT_FAILURE(rc)
                && pThis->u32Magic != RTLOCALIPCSESSION_MAGIC)
                return rc;

            int rc2 = RTCritSectEnter(&pThis->CritSect);
            AssertRC(rc2);
            if (pThis->fZeroByteRead)
            {
                Assert(pThis->cRefs);
                pThis->cRefs--;
                pThis->fIOPending = false;

                if (rc != VINF_SUCCESS)
                {
                    BOOL fRc = CancelIo(pThis->hNmPipe);
                    Assert(fRc == TRUE);
                }

                DWORD cbRead = 0;
                BOOL fRc = GetOverlappedResult(pThis->hNmPipe, &pThis->OverlappedIO, &cbRead, TRUE /*fWait*/);
                if (   !fRc
                    && RT_SUCCESS(rc))
                {
                    DWORD dwRc = GetLastError();
                    if (dwRc == ERROR_OPERATION_ABORTED)
                        rc = VERR_CANCELLED;
                    else
                        rc = RTErrConvertFromWin32(dwRc);
                }
            }

            if (RT_FAILURE(rc))
                break;
        }
    }

    int rc2 = RTCritSectLeave(&pThis->CritSect);
    if (RT_SUCCESS(rc))
        rc = rc2;

    return rc;
}
Ejemplo n.º 10
0
static int vboxInitLogging(const char *pszFilename, bool bGenNameSuffix)
{
    PRTLOGGER loggerRelease;
    static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
    RTUINT fFlags = RTLOGFLAGS_PREFIX_TIME_PROG;
#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    fFlags |= RTLOGFLAGS_USECRLF;
#endif
    char szError[RTPATH_MAX + 128] = "";
    const char * pszFilenameFmt;
    RTLOGDEST enmLogDest;
    if(pszFilename)
    {
        if(bGenNameSuffix)
            pszFilenameFmt = "%s.%ld.log";
        else
            pszFilenameFmt = "%s";
        enmLogDest = RTLOGDEST_FILE;
    }
    else
    {
        pszFilenameFmt = NULL;
        enmLogDest = RTLOGDEST_STDOUT;
    }

    int vrc = RTLogCreateEx(&loggerRelease, fFlags, "all",
                            "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, enmLogDest,
                            NULL /* pfnBeginEnd */, 0 /* cHistory */, 0 /* cbHistoryFileMax */, 0 /* uHistoryTimeMax */,
                            szError, sizeof(szError), pszFilenameFmt, pszFilename, RTTimeMilliTS());
    if (RT_SUCCESS(vrc))
    {
        /* some introductory information */
        RTTIMESPEC timeSpec;
        char szTmp[256];
        RTTimeSpecToString(RTTimeNow(&timeSpec), szTmp, sizeof(szTmp));
        RTLogRelLogger(loggerRelease, 0, ~0U,
                       "VBoxTestGL %s r%u %s (%s %s) release log\n"
#ifdef VBOX_BLEEDING_EDGE
                       "EXPERIMENTAL build " VBOX_BLEEDING_EDGE "\n"
#endif
                       "Log opened %s\n",
                       VBOX_VERSION_STRING, RTBldCfgRevision(), VBOX_BUILD_TARGET,
                       __DATE__, __TIME__, szTmp);

        vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp));
        if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
            RTLogRelLogger(loggerRelease, 0, ~0U, "OS Product: %s\n", szTmp);
        vrc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szTmp, sizeof(szTmp));
        if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
            RTLogRelLogger(loggerRelease, 0, ~0U, "OS Release: %s\n", szTmp);
        vrc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szTmp, sizeof(szTmp));
        if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
            RTLogRelLogger(loggerRelease, 0, ~0U, "OS Version: %s\n", szTmp);
        vrc = RTSystemQueryOSInfo(RTSYSOSINFO_SERVICE_PACK, szTmp, sizeof(szTmp));
        if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
            RTLogRelLogger(loggerRelease, 0, ~0U, "OS Service Pack: %s\n", szTmp);
//        RTLogRelLogger(loggerRelease, 0, ~0U, "Host RAM: %uMB RAM, available: %uMB\n",
//                       uHostRamMb, uHostRamAvailMb);
        /* the package type is interesting for Linux distributions */
        char szExecName[RTPATH_MAX];
        char *pszExecName = RTProcGetExecutablePath(szExecName, sizeof(szExecName));
        RTLogRelLogger(loggerRelease, 0, ~0U,
                       "Executable: %s\n"
                       "Process ID: %u\n"
                       "Package type: %s"
#ifdef VBOX_OSE
                       " (OSE)"
#endif
                       "\n",
                       pszExecName ? pszExecName : "unknown",
                       RTProcSelf(),
                       VBOX_PACKAGE_STRING);

        /* register this logger as the release logger */
        RTLogRelSetDefaultInstance(loggerRelease);

        return VINF_SUCCESS;
    }

    return vrc;
}
Ejemplo n.º 11
0
int main(int argc, char *argv[])
{
    /*
     * Initialize the VBox runtime without loading
     * the support driver.
     */
    int rc = RTR3InitExe(argc, &argv, 0);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstCollector: RTR3InitExe() -> %d\n", rc);
        return 1;
    }
    if (argc > 1 && !strcmp(argv[1], "-child"))
    {
        /* We have spawned ourselves as a child process -- scratch the leg */
        RTThreadSleep(1000000);
        return 1;
    }
#ifdef RT_OS_WINDOWS
    HRESULT hRes = CoInitialize(NULL);
    /*
     * Need to initialize security to access performance enumerators.
     */
    hRes = CoInitializeSecurity(
        NULL,
        -1,
        NULL,
        NULL,
        RPC_C_AUTHN_LEVEL_NONE,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL, EOAC_NONE, 0);
#endif

    pm::CollectorHAL *collector = pm::createHAL();
    if (!collector)
    {
        RTPrintf("tstCollector: createMetricFactory() failed\n", rc);
        return 1;
    }
#if 1
    pm::CollectorHints hints;
    hints.collectHostCpuLoad();
    hints.collectHostRamUsage();
    hints.collectProcessCpuLoad(RTProcSelf());
    hints.collectProcessRamUsage(RTProcSelf());

    uint64_t start;

    uint64_t hostUserStart, hostKernelStart, hostIdleStart;
    uint64_t hostUserStop, hostKernelStop, hostIdleStop, hostTotal;

    uint64_t processUserStart, processKernelStart, processTotalStart;
    uint64_t processUserStop, processKernelStop, processTotalStop;

    RTPrintf("tstCollector: TESTING - CPU load, sleeping for 5 sec\n");

    rc = collector->preCollect(hints, 0);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstCollector: preCollect() -> %Rrc\n", rc);
        return 1;
    }
    rc = collector->getRawHostCpuLoad(&hostUserStart, &hostKernelStart, &hostIdleStart);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstCollector: getRawHostCpuLoad() -> %Rrc\n", rc);
        return 1;
    }
    rc = collector->getRawProcessCpuLoad(RTProcSelf(), &processUserStart, &processKernelStart, &processTotalStart);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstCollector: getRawProcessCpuLoad() -> %Rrc\n", rc);
        return 1;
    }

    RTThreadSleep(5000); // Sleep for 5 seconds

    rc = collector->preCollect(hints, 0);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstCollector: preCollect() -> %Rrc\n", rc);
        return 1;
    }
    rc = collector->getRawHostCpuLoad(&hostUserStop, &hostKernelStop, &hostIdleStop);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstCollector: getRawHostCpuLoad() -> %Rrc\n", rc);
        return 1;
    }
    rc = collector->getRawProcessCpuLoad(RTProcSelf(), &processUserStop, &processKernelStop, &processTotalStop);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstCollector: getRawProcessCpuLoad() -> %Rrc\n", rc);
        return 1;
    }
    hostTotal = hostUserStop - hostUserStart
        + hostKernelStop - hostKernelStart
        + hostIdleStop - hostIdleStart;
    /*printf("tstCollector: host cpu user      = %f sec\n", (hostUserStop - hostUserStart) / 10000000.);
    printf("tstCollector: host cpu kernel    = %f sec\n", (hostKernelStop - hostKernelStart) / 10000000.);
    printf("tstCollector: host cpu idle      = %f sec\n", (hostIdleStop - hostIdleStart) / 10000000.);
    printf("tstCollector: host cpu total     = %f sec\n", hostTotal / 10000000.);*/
    RTPrintf("tstCollector: host cpu user      = %u.%u %%\n",
             (unsigned)((hostUserStop - hostUserStart) * 100 / hostTotal),
             (unsigned)((hostUserStop - hostUserStart) * 10000 / hostTotal % 100));
    RTPrintf("tstCollector: host cpu kernel    = %u.%u %%\n",
             (unsigned)((hostKernelStop - hostKernelStart) * 100 / hostTotal),
             (unsigned)((hostKernelStop - hostKernelStart) * 10000 / hostTotal % 100));
    RTPrintf("tstCollector: host cpu idle      = %u.%u %%\n",
             (unsigned)((hostIdleStop - hostIdleStart) * 100 / hostTotal),
             (unsigned)((hostIdleStop - hostIdleStart) * 10000 / hostTotal % 100));
    RTPrintf("tstCollector: process cpu user   = %u.%u %%\n",
             (unsigned)((processUserStop - processUserStart) * 100 / (processTotalStop - processTotalStart)),
             (unsigned)((processUserStop - processUserStart) * 10000 / (processTotalStop - processTotalStart) % 100));
    RTPrintf("tstCollector: process cpu kernel = %u.%u %%\n\n",
             (unsigned)((processKernelStop - processKernelStart) * 100 / (processTotalStop - processTotalStart)),
             (unsigned)((processKernelStop - processKernelStart) * 10000 / (processTotalStop - processTotalStart) % 100));

    RTPrintf("tstCollector: TESTING - CPU load, looping for 5 sec\n");
    rc = collector->preCollect(hints, 0);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstCollector: preCollect() -> %Rrc\n", rc);
        return 1;
    }
    rc = collector->getRawHostCpuLoad(&hostUserStart, &hostKernelStart, &hostIdleStart);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstCollector: getRawHostCpuLoad() -> %Rrc\n", rc);
        return 1;
    }
    rc = collector->getRawProcessCpuLoad(RTProcSelf(), &processUserStart, &processKernelStart, &processTotalStart);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstCollector: getRawProcessCpuLoad() -> %Rrc\n", rc);
        return 1;
    }
    start = RTTimeMilliTS();
    while(RTTimeMilliTS() - start < 5000)
        ; // Loop for 5 seconds
    rc = collector->preCollect(hints, 0);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstCollector: preCollect() -> %Rrc\n", rc);
        return 1;
    }
    rc = collector->getRawHostCpuLoad(&hostUserStop, &hostKernelStop, &hostIdleStop);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstCollector: getRawHostCpuLoad() -> %Rrc\n", rc);
        return 1;
    }
    rc = collector->getRawProcessCpuLoad(RTProcSelf(), &processUserStop, &processKernelStop, &processTotalStop);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstCollector: getRawProcessCpuLoad() -> %Rrc\n", rc);
        return 1;
    }
    hostTotal = hostUserStop - hostUserStart
        + hostKernelStop - hostKernelStart
        + hostIdleStop - hostIdleStart;
    RTPrintf("tstCollector: host cpu user      = %u.%u %%\n",
             (unsigned)((hostUserStop - hostUserStart) * 100 / hostTotal),
             (unsigned)((hostUserStop - hostUserStart) * 10000 / hostTotal % 100));
    RTPrintf("tstCollector: host cpu kernel    = %u.%u %%\n",
             (unsigned)((hostKernelStop - hostKernelStart) * 100 / hostTotal),
             (unsigned)((hostKernelStop - hostKernelStart) * 10000 / hostTotal % 100));
    RTPrintf("tstCollector: host cpu idle      = %u.%u %%\n",
             (unsigned)((hostIdleStop - hostIdleStart) * 100 / hostTotal),
             (unsigned)((hostIdleStop - hostIdleStart) * 10000 / hostTotal % 100));
    RTPrintf("tstCollector: process cpu user   = %u.%u %%\n",
             (unsigned)((processUserStop - processUserStart) * 100 / (processTotalStop - processTotalStart)),
             (unsigned)((processUserStop - processUserStart) * 10000 / (processTotalStop - processTotalStart) % 100));
    RTPrintf("tstCollector: process cpu kernel = %u.%u %%\n\n",
             (unsigned)((processKernelStop - processKernelStart) * 100 / (processTotalStop - processTotalStart)),
             (unsigned)((processKernelStop - processKernelStart) * 10000 / (processTotalStop - processTotalStart) % 100));

    RTPrintf("tstCollector: TESTING - Memory usage\n");

    ULONG total, used, available, processUsed;

    rc = collector->getHostMemoryUsage(&total, &used, &available);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstCollector: getHostMemoryUsage() -> %Rrc\n", rc);
        return 1;
    }
    rc = collector->getProcessMemoryUsage(RTProcSelf(), &processUsed);
    if (RT_FAILURE(rc))
    {
        RTPrintf("tstCollector: getProcessMemoryUsage() -> %Rrc\n", rc);
        return 1;
    }
    RTPrintf("tstCollector: host mem total     = %lu kB\n", total);
    RTPrintf("tstCollector: host mem used      = %lu kB\n", used);
    RTPrintf("tstCollector: host mem available = %lu kB\n", available);
    RTPrintf("tstCollector: process mem used   = %lu kB\n\n", processUsed);
#endif
#if 1
    rc = testNetwork(collector);
#endif
#if 1
    rc = testFsUsage(collector);
#endif
#if 1
    rc = testDisk(collector);
#endif
#if 1
    RTPrintf("tstCollector: TESTING - Performance\n\n");

    measurePerformance(collector, argv[0], 100);
#endif

    delete collector;

    printf ("\ntstCollector FINISHED.\n");

    return rc;
}
Ejemplo n.º 12
0
RTDECL(uint64_t) RTTimeSystemMilliTS(void)
{
    return RTTimeMilliTS();
}
Ejemplo n.º 13
0
/**
 * Gets the current TMCLOCK_REAL time.
 *
 * @returns Real time.
 * @param   pVM             Pointer to the VM.
 */
VMM_INT_DECL(uint64_t) TMRealGet(PVM pVM)
{
    NOREF(pVM);
    return RTTimeMilliTS();
}
Ejemplo n.º 14
0
static void tstTraffic(unsigned cThreads, unsigned cSecs)
{
    RTTestSubF(g_hTest, "Traffic - %u threads per direction, %u sec", cThreads, cSecs);

    /*
     * Create X worker threads which drives in the south/north direction and Y
     * worker threads which drives in the west/east direction.  Let them drive
     * in a loop for 15 seconds with slight delays between some of the runs and
     * then check the numbers.
     */

    /* init */
    RTTHREAD ahThreadsX[8];
    for (unsigned i = 0; i < RT_ELEMENTS(ahThreadsX); i++)
        ahThreadsX[i] = NIL_RTTHREAD;
    AssertRelease(RT_ELEMENTS(ahThreadsX) >= cThreads);

    RTTHREAD ahThreadsY[8];
    for (unsigned i = 0; i < RT_ELEMENTS(ahThreadsY); i++)
        ahThreadsY[i] = NIL_RTTHREAD;
    AssertRelease(RT_ELEMENTS(ahThreadsY) >= cThreads);

    g_cNSCrossings      = 0;
    g_cEWCrossings      = 0;
    g_cSecs             = cSecs;
    g_u64StartMilliTS   = RTTimeMilliTS();

    /* create */
    RTTEST_CHECK_RC_RETV(g_hTest, RTSemXRoadsCreate(&g_hXRoads), VINF_SUCCESS);

    int rc = VINF_SUCCESS;
    for (unsigned i = 0; i < cThreads && RT_SUCCESS(rc); i++)
    {
        rc = RTThreadCreateF(&ahThreadsX[i], tstTrafficNSThread, (void *)(uintptr_t)i, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "NS-%u", i);
        RTTEST_CHECK_RC_OK(g_hTest, rc);
    }

    for (unsigned i = 0; i < cThreads && RT_SUCCESS(rc); i++)
    {
        rc = RTThreadCreateF(&ahThreadsX[i], tstTrafficEWThread, (void *)(uintptr_t)i, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "NS-%u", i);
        RTTEST_CHECK_RC_OK(g_hTest, rc);
    }

    /* wait */
    for (unsigned i = 0; i < RT_ELEMENTS(ahThreadsX); i++)
        if (ahThreadsX[i] != NIL_RTTHREAD)
        {
            int rc2 = RTThreadWaitNoResume(ahThreadsX[i], (60 + cSecs) * 1000, NULL);
            RTTEST_CHECK_RC_OK(g_hTest, rc2);
        }

    for (unsigned i = 0; i < RT_ELEMENTS(ahThreadsY); i++)
        if (ahThreadsY[i] != NIL_RTTHREAD)
        {
            int rc2 = RTThreadWaitNoResume(ahThreadsY[i], (60 + cSecs) * 1000, NULL);
            RTTEST_CHECK_RC_OK(g_hTest, rc2);
        }

    RTTEST_CHECK_MSG_RETV(g_hTest, g_cEWCrossings > 10 && g_cNSCrossings,
                          (g_hTest, "cEWCrossings=%u g_cNSCrossings=%u\n", g_cEWCrossings, g_cNSCrossings));
    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "cNSCrossings=%u\n", g_cNSCrossings);
    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "cEWCrossings=%u\n", g_cEWCrossings);
}
/**
 * Thread function waiting for credentials to arrive.
 *
 * @return  IPRT status code.
 * @param   hThreadSelf             Thread handle.
 * @param   pvUser                  Pointer to a PAMVBOXTHREAD structure providing
 *                                  required data used / set by the thread.
 */
static DECLCALLBACK(int) pam_vbox_wait_thread(RTTHREAD hThreadSelf, void *pvUser)
{
    RT_NOREF1(hThreadSelf);
    PPAMVBOXTHREAD pUserData = (PPAMVBOXTHREAD)pvUser;
    AssertPtr(pUserData);

    int rc = VINF_SUCCESS;
    /* Get current time stamp to later calculate rest of timeout left. */
    uint64_t u64StartMS = RTTimeMilliTS();

#ifdef VBOX_WITH_GUEST_PROPS
    uint32_t uClientID = 0;
    rc = VbglR3GuestPropConnect(&uClientID);
    if (RT_FAILURE(rc))
    {
        pam_vbox_error(pUserData->hPAM, "pam_vbox_wait_thread: Unable to connect to guest property service, rc=%Rrc\n", rc);
    }
    else
    {
        pam_vbox_log(pUserData->hPAM, "pam_vbox_wait_thread: clientID=%u\n", uClientID);
#endif
        for (;;)
        {
#ifdef VBOX_WITH_GUEST_PROPS
            if (uClientID)
            {
                rc = pam_vbox_wait_prop(pUserData->hPAM, uClientID,
                                        "/VirtualBox/GuestAdd/PAM/CredsWaitAbort",
                                        500 /* Wait 500ms, same as VBoxGINA/VBoxCredProv. */);
                switch (rc)
                {
                    case VINF_SUCCESS:
                        /* Somebody (guest/host) wants to abort waiting for credentials. */
                        break;

                    case VERR_INTERRUPTED:
                        pam_vbox_error(pUserData->hPAM, "pam_vbox_wait_thread: The abort notification request timed out or was interrupted\n");
                        break;

                    case VERR_TIMEOUT:
                        /* We did not receive an abort message within time. */
                        break;

                    case VERR_TOO_MUCH_DATA:
                        pam_vbox_error(pUserData->hPAM, "pam_vbox_wait_thread: Temporarily unable to get abort notification\n");
                        break;

                    default:
                        pam_vbox_error(pUserData->hPAM, "pam_vbox_wait_thread: The abort notification request failed with rc=%Rrc\n", rc);
                        break;
                }

                if (RT_SUCCESS(rc)) /* Abort waiting. */
                {
                    pam_vbox_log(pUserData->hPAM, "pam_vbox_wait_thread: Got notification to abort waiting\n");
                    rc = VERR_CANCELLED;
                    break;
                }
            }
#endif
            if (   RT_SUCCESS(rc)
                || rc == VERR_TIMEOUT)
            {
                rc = pam_vbox_check_creds(pUserData->hPAM);
                if (RT_SUCCESS(rc))
                {
                    /* Credentials retrieved. */
                    break; /* Thread no longer is required, bail out. */
                }
                else if (rc == VERR_NOT_FOUND)
                {
                    /* No credentials found, but try next round (if there's
                     * time left for) ... */
#ifndef VBOX_WITH_GUEST_PROPS
                    RTThreadSleep(500); /* Wait 500 ms. */
#endif
                }
                else
                    break; /* Something bad happend ... */
            }
            else
                break;

            /* Calculate timeout value left after process has been started.  */
            uint64_t u64Elapsed = RTTimeMilliTS() - u64StartMS;
            /* Is it time to bail out? */
            if (pUserData->uTimeoutMS < u64Elapsed)
            {
                pam_vbox_log(pUserData->hPAM, "pam_vbox_wait_thread: Waiting thread has reached timeout (%dms), exiting ...\n",
                             pUserData->uTimeoutMS);
                rc = VERR_TIMEOUT;
                break;
            }
        }
#ifdef VBOX_WITH_GUEST_PROPS
    }
    VbglR3GuestPropDisconnect(uClientID);
#endif

    /* Save result. */
    pUserData->rc = rc; /** @todo Use ASMAtomicXXX? */

    int rc2 = RTThreadUserSignal(RTThreadSelf());
    AssertRC(rc2);

    pam_vbox_log(pUserData->hPAM, "pam_vbox_wait_thread: Waiting thread returned with rc=%Rrc\n", rc);
    return rc;
}
Ejemplo n.º 16
0
int main()
{
    /*
     * Init runtime
     */
    unsigned cErrors = 0;
    int rc = RTR3InitExeNoArguments(0);
    if (RT_FAILURE(rc))
        return RTMsgInitFailure(rc);

    /*
     * Check that the clock is reliable.
     */
    RTPrintf("tstTimer: TESTING - RTTimeNanoTS() for 2sec\n");
    uint64_t uTSMillies = RTTimeMilliTS();
    uint64_t uTSBegin = RTTimeNanoTS();
    uint64_t uTSLast = uTSBegin;
    uint64_t uTSDiff;
    uint64_t cIterations = 0;

    do
    {
        uint64_t uTS = RTTimeNanoTS();
        if (uTS < uTSLast)
        {
            RTPrintf("tstTimer: FAILURE - RTTimeNanoTS() is unreliable. uTS=%RU64 uTSLast=%RU64\n", uTS, uTSLast);
            cErrors++;
        }
        if (++cIterations > (2*1000*1000*1000))
        {
            RTPrintf("tstTimer: FAILURE - RTTimeNanoTS() is unreliable. cIterations=%RU64 uTS=%RU64 uTSBegin=%RU64\n", cIterations, uTS, uTSBegin);
            return 1;
        }
        uTSLast = uTS;
        uTSDiff = uTSLast - uTSBegin;
    } while (uTSDiff < (2*1000*1000*1000));
    uTSMillies = RTTimeMilliTS() - uTSMillies;
    if (uTSMillies >= 2500 || uTSMillies <= 1500)
    {
        RTPrintf("tstTimer: FAILURE - uTSMillies=%RI64 uTSBegin=%RU64 uTSLast=%RU64 uTSDiff=%RU64\n",
                 uTSMillies, uTSBegin, uTSLast, uTSDiff);
        cErrors++;
    }
    if (!cErrors)
        RTPrintf("tstTimer: OK      - RTTimeNanoTS()\n");

    /*
     * Tests.
     */
    static struct
    {
        unsigned uMicroInterval;
        unsigned uMilliesWait;
        unsigned cLower;
        unsigned cUpper;
    } aTests[] =
    {
        { 32000, 2000, 0, 0 },
        { 20000, 2000, 0, 0 },
        { 10000, 2000, 0, 0 },
        {  8000, 2000, 0, 0 },
        {  2000, 2000, 0, 0 },
        {  1000, 2000, 0, 0 },
        {   500, 5000, 0, 0 },
        {   200, 5000, 0, 0 },
        {   100, 5000, 0, 0 }
    };

    unsigned i = 0;
    for (i = 0; i < RT_ELEMENTS(aTests); i++)
    {
        aTests[i].cLower = (aTests[i].uMilliesWait*1000 - aTests[i].uMilliesWait*100) / aTests[i].uMicroInterval;
        aTests[i].cUpper = (aTests[i].uMilliesWait*1000 + aTests[i].uMilliesWait*100) / aTests[i].uMicroInterval;
        gu64Norm = aTests[i].uMicroInterval*1000;

        RTPrintf("\n"
                 "tstTimer: TESTING - %d us interval, %d ms wait, expects %d-%d ticks.\n",
                 aTests[i].uMicroInterval, aTests[i].uMilliesWait, aTests[i].cLower, aTests[i].cUpper);

        /*
         * Start timer which ticks every 10ms.
         */
        gcTicks = 0;
        PRTTIMER pTimer;
        gu64Max = 0;
        gu64Min = UINT64_MAX;
        gu64Prev = 0;
        RT_ZERO(cFrequency);
#ifdef RT_OS_WINDOWS
        if (aTests[i].uMicroInterval < 1000)
            continue;
        rc = RTTimerCreate(&pTimer, aTests[i].uMicroInterval / 1000, TimerCallback, NULL);
#else
        rc = RTTimerCreateEx(&pTimer, aTests[i].uMicroInterval * (uint64_t)1000, 0, TimerCallback, NULL);
#endif
        if (RT_FAILURE(rc))
        {
            RTPrintf("tstTimer: FAILURE - RTTimerCreateEx(,%u*1M,,,) -> %Rrc\n", aTests[i].uMicroInterval, rc);
            cErrors++;
            continue;
        }

        /*
         * Start the timer and active waiting for the requested test period.
         */
        uTSBegin = RTTimeNanoTS();
#ifndef RT_OS_WINDOWS
        rc = RTTimerStart(pTimer, 0);
        if (RT_FAILURE(rc))
        {
            RTPrintf("tstTimer: FAILURE - RTTimerStart(,0) -> %Rrc\n", rc);
            cErrors++;
        }
#endif

        while (RTTimeNanoTS() - uTSBegin < (uint64_t)aTests[i].uMilliesWait * 1000000)
            /* nothing */;

        /* destroy the timer */
        uint64_t uTSEnd = RTTimeNanoTS();
        uTSDiff = uTSEnd - uTSBegin;
        rc = RTTimerDestroy(pTimer);
        if (RT_FAILURE(rc))
        {
            RTPrintf("tstTimer: FAILURE - RTTimerDestroy() -> %d gcTicks=%d\n", rc, gcTicks);
            cErrors++;
        }

        RTPrintf("tstTimer: uTS=%RI64 (%RU64 - %RU64)\n", uTSDiff, uTSBegin, uTSEnd);
        unsigned cTicks = gcTicks;
        RTThreadSleep(aTests[i].uMicroInterval/1000 * 3);
        if (gcTicks != cTicks)
        {
            RTPrintf("tstTimer: FAILURE - RTTimerDestroy() didn't really stop the timer! gcTicks=%d cTicks=%d\n", gcTicks, cTicks);
            cErrors++;
            continue;
        }

        /*
         * Check the number of ticks.
         */
        if (gcTicks < aTests[i].cLower)
        {
            RTPrintf("tstTimer: FAILURE - Too few ticks gcTicks=%d (expected %d-%d)", gcTicks, aTests[i].cUpper, aTests[i].cLower);
            cErrors++;
        }
        else if (gcTicks > aTests[i].cUpper)
        {
            RTPrintf("tstTimer: FAILURE - Too many ticks gcTicks=%d (expected %d-%d)", gcTicks, aTests[i].cUpper, aTests[i].cLower);
            cErrors++;
        }
        else
            RTPrintf("tstTimer: OK      - gcTicks=%d",  gcTicks);
        RTPrintf(" min=%RU64 max=%RU64\n", gu64Min, gu64Max);

        for (int j = 0; j < (int)RT_ELEMENTS(cFrequency); j++)
        {
            uint32_t len = cFrequency[j] * 70 / gcTicks;
            uint32_t deviation = j - RT_ELEMENTS(cFrequency) / 2;
            uint64_t u64FreqPercent = (uint64_t)cFrequency[j] * 10000 / gcTicks;
            uint64_t u64FreqPercentFrac = u64FreqPercent % 100;
            u64FreqPercent = u64FreqPercent / 100;
            RTPrintf("%+4d%c %6u %3llu.%02llu%% ",
                     deviation, deviation == 0 ? ' ' : '%', cFrequency[j],
                     u64FreqPercent, u64FreqPercentFrac);
            for (unsigned k = 0; k < len; k++)
                RTPrintf("*");
            RTPrintf("\n");
        }
    }

    /*
     * Summary.
     */
    if (!cErrors)
        RTPrintf("tstTimer: SUCCESS\n");
    else
        RTPrintf("tstTimer: FAILURE %d errors\n", cErrors);
    return !!cErrors;
}
Console::teleporterSrcThreadWrapper(RTTHREAD hThread, void *pvUser)
{
    TeleporterStateSrc *pState = (TeleporterStateSrc *)pvUser;

    /*
     * Console::teleporterSrc does the work, we just grab onto the VM handle
     * and do the cleanups afterwards.
     */
    SafeVMPtr ptrVM(pState->mptrConsole);
    HRESULT hrc = ptrVM.rc();

    if (SUCCEEDED(hrc))
        hrc = pState->mptrConsole->teleporterSrc(pState);

    /* Close the connection ASAP on so that the other side can complete. */
    if (pState->mhSocket != NIL_RTSOCKET)
    {
        RTTcpClientClose(pState->mhSocket);
        pState->mhSocket = NIL_RTSOCKET;
    }

    /* Aaarg! setMachineState trashes error info on Windows, so we have to
       complete things here on failure instead of right before cleanup. */
    if (FAILED(hrc))
        pState->mptrProgress->notifyComplete(hrc);

    /* We can no longer be canceled (success), or it doesn't matter any longer (failure). */
    pState->mptrProgress->setCancelCallback(NULL, NULL);

    /*
     * Write lock the console before resetting mptrCancelableProgress and
     * fixing the state.
     */
    AutoWriteLock autoLock(pState->mptrConsole COMMA_LOCKVAL_SRC_POS);
    pState->mptrConsole->mptrCancelableProgress.setNull();

    VMSTATE const        enmVMState      = VMR3GetStateU(pState->mpUVM);
    MachineState_T const enmMachineState = pState->mptrConsole->mMachineState;
    if (SUCCEEDED(hrc))
    {
        /*
         * Automatically shut down the VM on success.
         *
         * Note! We have to release the VM caller object or we'll deadlock in
         *       powerDown.
         */
        AssertLogRelMsg(enmVMState == VMSTATE_SUSPENDED, ("%s\n", VMR3GetStateName(enmVMState)));
        AssertLogRelMsg(enmMachineState == MachineState_TeleportingPausedVM, ("%s\n", Global::stringifyMachineState(enmMachineState)));

        ptrVM.release();

        pState->mptrConsole->mVMIsAlreadyPoweringOff = true; /* (Make sure we stick in the TeleportingPausedVM state.) */
        hrc = pState->mptrConsole->powerDown();
        pState->mptrConsole->mVMIsAlreadyPoweringOff = false;

        pState->mptrProgress->notifyComplete(hrc);
    }
    else
    {
        /*
         * Work the state machinery on failure.
         *
         * If the state is no longer 'Teleporting*', some other operation has
         * canceled us and there is nothing we need to do here.  In all other
         * cases, we've failed one way or another.
         */
        if (   enmMachineState == MachineState_Teleporting
                || enmMachineState == MachineState_TeleportingPausedVM
           )
        {
            if (pState->mfUnlockedMedia)
            {
                ErrorInfoKeeper Oak;
                HRESULT hrc2 = pState->mptrConsole->mControl->LockMedia();
                if (FAILED(hrc2))
                {
                    uint64_t StartMS = RTTimeMilliTS();
                    do
                    {
                        RTThreadSleep(2);
                        hrc2 = pState->mptrConsole->mControl->LockMedia();
                    } while (   FAILED(hrc2)
                                && RTTimeMilliTS() - StartMS < 2000);
                }
                if (SUCCEEDED(hrc2))
                    pState->mfUnlockedMedia = true;
                else
                    LogRel(("FATAL ERROR: Failed to re-take the media locks. hrc2=%Rhrc\n", hrc2));
            }

            switch (enmVMState)
            {
            case VMSTATE_RUNNING:
            case VMSTATE_RUNNING_LS:
            case VMSTATE_DEBUGGING:
            case VMSTATE_DEBUGGING_LS:
            case VMSTATE_POWERING_OFF:
            case VMSTATE_POWERING_OFF_LS:
            case VMSTATE_RESETTING:
            case VMSTATE_RESETTING_LS:
                Assert(!pState->mfSuspendedByUs);
                Assert(!pState->mfUnlockedMedia);
                pState->mptrConsole->setMachineState(MachineState_Running);
                break;

            case VMSTATE_GURU_MEDITATION:
            case VMSTATE_GURU_MEDITATION_LS:
                pState->mptrConsole->setMachineState(MachineState_Stuck);
                break;

            case VMSTATE_FATAL_ERROR:
            case VMSTATE_FATAL_ERROR_LS:
                pState->mptrConsole->setMachineState(MachineState_Paused);
                break;

            default:
                AssertMsgFailed(("%s\n", VMR3GetStateName(enmVMState)));
            case VMSTATE_SUSPENDED:
            case VMSTATE_SUSPENDED_LS:
            case VMSTATE_SUSPENDING:
            case VMSTATE_SUSPENDING_LS:
            case VMSTATE_SUSPENDING_EXT_LS:
                if (!pState->mfUnlockedMedia)
                {
                    pState->mptrConsole->setMachineState(MachineState_Paused);
                    if (pState->mfSuspendedByUs)
                    {
                        autoLock.release();
                        int rc = VMR3Resume(VMR3GetVM(pState->mpUVM));
                        AssertLogRelMsgRC(rc, ("VMR3Resume -> %Rrc\n", rc));
                        autoLock.acquire();
                    }
                }
                else
                {
                    /* Faking a guru meditation is the best I can think of doing here... */
                    pState->mptrConsole->setMachineState(MachineState_Stuck);
                }
                break;
            }
        }
    }
    autoLock.release();

    /*
     * Cleanup.
     */
    Assert(pState->mhSocket == NIL_RTSOCKET);
    delete pState;

    return VINF_SUCCESS; /* ignored */
}
/* The function checks the URB queue for completed URBs. Also if the client
 * has requested URB polling, the function will send URB poll requests.
 */
static DECLCALLBACK(int) iface_ReapURB(PREMOTEUSBDEVICE pDevice, uint32_t u32Millies, void **ppvURB,
                                       uint32_t *pu32Len, uint32_t *pu32Err)
{
    int rc = VINF_SUCCESS;

    LogFlow(("RemoteUSBBackend::iface_ReapURB %d ms\n", u32Millies));

    if (pDevice->fFailed)
    {
        return VERR_VUSB_DEVICE_NOT_ATTACHED;
    }

    RemoteUSBBackend *pThis = pDevice->pOwner;

    /* Wait for transaction completion. */
    uint64_t u64StartTime = RTTimeMilliTS();

    if (pThis->pollingEnabledURB())
    {
        VRDE_USB_REQ_REAP_URB_PARM parm;

        parm.code = VRDE_USB_REQ_REAP_URB;

        pThis->VRDPServer()->SendUSBRequest(pDevice->u32ClientId, &parm, sizeof(parm));
    }

    REMOTEUSBQURB *qurb = NULL;

    for (;;)
    {
        uint32_t u32ClientId;

        if (ASMAtomicXchgBool(&pDevice->fWokenUp, false))
            break;

        /* Scan queued URBs, look for completed. */
        requestDevice(pDevice);

        u32ClientId = pDevice->u32ClientId;

        qurb = pDevice->pHeadQURBs;

        while (qurb)
        {
            if (qurb->fCompleted)
            {
                /* Remove this completed urb from the queue. */
                if (qurb->prev)
                {
                    qurb->prev->next = qurb->next;
                }
                else
                {
                    pDevice->pHeadQURBs = qurb->next;
                }

                if (qurb->next)
                {
                    qurb->next->prev = qurb->prev;
                }
                else
                {
                    pDevice->pTailQURBs = qurb->prev;
                }

                qurb->next = NULL;
                qurb->prev = NULL;

                break;
            }

            qurb = qurb->next;
        }

        releaseDevice(pDevice);

        if (   qurb
            || !pDevice->pHeadQURBs
            || u32Millies == 0
            || pDevice->fFailed
            || (RTTimeMilliTS() - u64StartTime >= (uint64_t)u32Millies))
        {
            /* Got an URB or do not have to wait for an URB. */
            break;
        }

        LogFlow(("RemoteUSBBackend::iface_ReapURB iteration.\n"));

        RTThreadSleep(10);

        if (pThis->pollingEnabledURB())
        {
            VRDE_USB_REQ_REAP_URB_PARM parm;

            parm.code = VRDE_USB_REQ_REAP_URB;

            pThis->VRDPServer()->SendUSBRequest(u32ClientId, &parm, sizeof(parm));
        }
    }

    LogFlow(("RemoteUSBBackend::iface_ReapURB completed in %lld ms, qurb = %p\n", RTTimeMilliTS () - u64StartTime, qurb));

    if (!qurb)
    {
        *ppvURB = NULL;
        *pu32Len = 0;
        *pu32Err = VUSBSTATUS_OK;
    }
    else
    {
        *ppvURB = qurb->pvURB;
        *pu32Len = qurb->u32Len;
        *pu32Err = qurb->u32Err;

#ifdef LOG_ENABLED
        Log(("URB len = %d, data = %p\n", qurb->u32Len, qurb->pvURB));
        if (qurb->u32Len)
        {
            Log(("Received URB content:\n%.*Rhxd\n", qurb->u32Len, qurb->pvData));
        }
#endif

        qurbFree(qurb);
    }

    return rc;
}
Ejemplo n.º 19
0
int USBProxyBackendUsbIp::wait(RTMSINTERVAL aMillies)
{
    int rc = VINF_SUCCESS;
    bool fDeviceListChangedOrWokenUp = false;

    /* Try to reconnect once when we enter if we lost the connection earlier. */
    if (m->hSocket == NIL_RTSOCKET)
        rc = reconnect();

    /* Query a new device list upon entering. */
    if (m->enmRecvState == kUsbIpRecvState_None)
    {
        rc = startListExportedDevicesReq();
        if (RT_FAILURE(rc))
            disconnect();
    }

    /*
     * Because the USB/IP protocol doesn't specify a way to get notified about
     * new or removed exported devices we have to poll the host periodically for
     * a new device list and compare it with the previous one notifying the proxy
     * service about changes.
     */
    while (   !fDeviceListChangedOrWokenUp
           && (aMillies == RT_INDEFINITE_WAIT || aMillies > 0)
           && RT_SUCCESS(rc))
    {
        RTMSINTERVAL msWait = aMillies;
        uint64_t msPollStart = RTTimeMilliTS();
        uint32_t uIdReady = 0;
        uint32_t fEventsRecv = 0;

        /* Limit the waiting time to 1sec so we can either reconnect or get a new device list. */
        if (m->hSocket == NIL_RTSOCKET || m->enmRecvState == kUsbIpRecvState_None)
            msWait = RT_MIN(1000, aMillies);

        rc = RTPoll(m->hPollSet, msWait, &fEventsRecv, &uIdReady);
        if (RT_SUCCESS(rc))
        {
            if (uIdReady == USBIP_POLL_ID_PIPE)
            {
                /* Drain the wakeup pipe. */
                char bRead = 0;
                size_t cbRead = 0;

                rc = RTPipeRead(m->hWakeupPipeR, &bRead, 1, &cbRead);
                Assert(RT_SUCCESS(rc) && cbRead == 1);
                fDeviceListChangedOrWokenUp = true;
            }
            else if (uIdReady == USBIP_POLL_ID_SOCKET)
            {
                if (fEventsRecv & RTPOLL_EVT_ERROR)
                    rc = VERR_NET_SHUTDOWN;
                else
                    rc = receiveData();
                if (RT_SUCCESS(rc))
                {
                    /*
                     * If we are in the none state again we received the previous request
                     * and have a new device list to compare the old against.
                     */
                    if (m->enmRecvState == kUsbIpRecvState_None)
                    {
                        if (hasDevListChanged(m->pHead))
                            fDeviceListChangedOrWokenUp = true;

                        /* Update to the new list in any case now that we have it anyway. */
                        RTSemFastMutexRequest(m->hMtxDevices);
                        freeDeviceList(m->pUsbDevicesCur);
                        m->cUsbDevicesCur = m->cDevicesCur;
                        m->pUsbDevicesCur = m->pHead;
                        RTSemFastMutexRelease(m->hMtxDevices);

                        m->pHead = NULL;
                        resetRecvState();
                    }
                }
                else if (rc == VERR_NET_SHUTDOWN || rc == VERR_BROKEN_PIPE)
                {
                    LogRelMax(10, ("USB/IP: Lost connection to host \"%s\", trying to reconnect...\n", m->pszHost));
                    disconnect();
                    rc = VINF_SUCCESS;
                }
            }
            else
            {
                AssertMsgFailed(("Invalid poll ID returned\n"));
                rc = VERR_INVALID_STATE;
            }
            aMillies -= (RTTimeMilliTS() - msPollStart);
        }
        else if (rc == VERR_TIMEOUT)
        {
            aMillies -= msWait;
            if (aMillies)
            {
                /* Try to reconnect and start a new request if we lost the connection before. */
                if (m->hSocket == NIL_RTSOCKET)
                    rc = reconnect();

                if (RT_SUCCESS(rc))
                    rc = startListExportedDevicesReq();
            }
        }
    }

    return rc;
}
Ejemplo n.º 20
0
/**
 * Get an entry from an mbox.
 */
u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout)
{
    int rc;
    RTMSINTERVAL cMillies;
    uint64_t tsStart, tsEnd;

    Assert(mbox != NULL);
    tsStart = RTTimeMilliTS();
    if (timeout == 0)
        cMillies = RT_INDEFINITE_WAIT;
    else
        cMillies = timeout;
    rc = LWIPMutexRequest(mbox->mutex, cMillies);
    if (rc == VERR_TIMEOUT)
        return SYS_ARCH_TIMEOUT;
    AssertRC(rc);
    while (mbox->head == mbox->tail)
    {
        /* mbox is empty, have to wait until a slot is filled. */
        rc = LWIPMutexRelease(mbox->mutex);
        AssertRC(rc);
        if (timeout != 0)
        {
            tsEnd = RTTimeMilliTS();
            if (tsEnd - tsStart >= cMillies)
                return SYS_ARCH_TIMEOUT;
            cMillies -= tsEnd - tsStart;
        }
        rc = RTSemEventMultiWait(mbox->nonempty, cMillies);
        if (rc == VERR_TIMEOUT)
            return SYS_ARCH_TIMEOUT;
        AssertRC(rc);
        if (timeout != 0)
        {
            tsEnd = RTTimeMilliTS();
            if (tsEnd - tsStart >= cMillies)
                return SYS_ARCH_TIMEOUT;
            cMillies -= tsEnd - tsStart;
        }
        rc = LWIPMutexRequest(mbox->mutex, cMillies);
        if (rc == VERR_TIMEOUT)
            return SYS_ARCH_TIMEOUT;
        AssertRC(rc);
    }
    if ((mbox->head + 1) % MBOX_ENTRIES_MAX == mbox->tail)
    {
        rc = RTSemEventMultiSignal(mbox->nonfull);
        AssertRC(rc);
    }
    if (msg != NULL)
        *msg = mbox->apvEntries[mbox->tail];
    mbox->tail++;
    mbox->tail %= MBOX_ENTRIES_MAX;
    rc = RTSemEventMultiSignal(mbox->nonfull);
    if (mbox->head == mbox->tail)
    {
        rc = RTSemEventMultiReset(mbox->nonempty);
        AssertRC(rc);
    }
    rc = LWIPMutexRelease(mbox->mutex);
    AssertRC(rc);
    tsEnd = RTTimeMilliTS();
    return tsEnd - tsStart;
}
Ejemplo n.º 21
0
RTDECL(int) RTPipeSelectOne(RTPIPE hPipe, RTMSINTERVAL cMillies)
{
    RTPIPEINTERNAL *pThis = hPipe;
    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    AssertReturn(pThis->u32Magic == RTPIPE_MAGIC, VERR_INVALID_HANDLE);

    uint64_t const StartMsTS = RTTimeMilliTS();

    int rc = RTCritSectEnter(&pThis->CritSect);
    if (RT_FAILURE(rc))
        return rc;
    for (unsigned iLoop = 0;; iLoop++)
    {
        HANDLE  hWait = INVALID_HANDLE_VALUE;
        if (pThis->fRead)
        {
            if (pThis->fIOPending)
                hWait = pThis->Overlapped.hEvent;
            else
            {
                /* Peek at the pipe buffer and see how many bytes it contains. */
                DWORD cbAvailable;
                if (   PeekNamedPipe(pThis->hPipe, NULL, 0, NULL, &cbAvailable, NULL)
                    && cbAvailable > 0)
                {
                    rc = VINF_SUCCESS;
                    break;
                }

                /* Start a zero byte read operation that we can wait on. */
                if (cMillies == 0)
                {
                    rc = VERR_TIMEOUT;
                    break;
                }
                AssertBreakStmt(pThis->cUsers == 0, rc = VERR_INTERNAL_ERROR_5);
                rc = ResetEvent(pThis->Overlapped.hEvent); Assert(rc == TRUE);
                DWORD cbRead = 0;
                if (ReadFile(pThis->hPipe, pThis->abBuf, 0, &cbRead, &pThis->Overlapped))
                {
                    rc = VINF_SUCCESS;
                    if (iLoop > 10)
                        RTThreadYield();
                }
                else if (GetLastError() == ERROR_IO_PENDING)
                {
                    pThis->cUsers++;
                    pThis->fIOPending = true;
                    pThis->fZeroByteRead = true;
                    hWait = pThis->Overlapped.hEvent;
                }
                else
                    rc = RTErrConvertFromWin32(GetLastError());
            }
        }
        else
        {
            if (pThis->fIOPending)
            {
                rc = rtPipeWriteCheckCompletion(pThis);
                if (RT_FAILURE(rc))
                    break;
            }
            if (pThis->fIOPending)
                hWait = pThis->Overlapped.hEvent;
            else
            {
                FILE_PIPE_LOCAL_INFORMATION Info;
                if (rtPipeQueryInfo(pThis, &Info))
                {
                    /* Check for broken pipe. */
                    if (Info.NamedPipeState == FILE_PIPE_CLOSING_STATE)
                    {
                        rc = VERR_BROKEN_PIPE;
                        break;
                    }
                    /* Check for available write buffer space. */
                    else if (Info.WriteQuotaAvailable > 0)
                    {
                        pThis->fPromisedWritable = false;
                        rc = VINF_SUCCESS;
                        break;
                    }
                    /* delayed buffer alloc or timeout: phony promise
                       later: See if we still can associate a semaphore with
                              the pipe, like on OS/2. */
                    else if (   Info.OutboundQuota == 0
                             || cMillies)
                    {
                        pThis->fPromisedWritable = true;
                        rc = VINF_SUCCESS;
                        break;
                    }
                }
                else
                {
                    pThis->fPromisedWritable = true;
                    rc = VINF_SUCCESS;
                    break;
                }
            }
        }
        if (RT_FAILURE(rc))
            break;

        /*
         * Check for timeout.
         */
        DWORD cMsMaxWait = INFINITE;
        if (   cMillies != RT_INDEFINITE_WAIT
            && (   hWait != INVALID_HANDLE_VALUE
                || iLoop > 10)
           )
        {
            uint64_t cElapsed = RTTimeMilliTS() - StartMsTS;
            if (cElapsed >= cMillies)
            {
                rc = VERR_TIMEOUT;
                break;
            }
            cMsMaxWait = cMillies - (uint32_t)cElapsed;
        }

        /*
         * Wait.
         */
        if (hWait != INVALID_HANDLE_VALUE)
        {
            RTCritSectLeave(&pThis->CritSect);

            DWORD dwRc = WaitForSingleObject(hWait, cMsMaxWait);
            if (dwRc == WAIT_OBJECT_0)
                rc = VINF_SUCCESS;
            else if (dwRc == WAIT_TIMEOUT)
                rc = VERR_TIMEOUT;
            else if (dwRc == WAIT_ABANDONED)
                rc = VERR_INVALID_HANDLE;
            else
                rc = RTErrConvertFromWin32(GetLastError());
            if (   RT_FAILURE(rc)
                && pThis->u32Magic != RTPIPE_MAGIC)
                return rc;

            RTCritSectEnter(&pThis->CritSect);
            if (pThis->fZeroByteRead)
            {
                pThis->cUsers--;
                pThis->fIOPending = false;
                if (rc != VINF_SUCCESS)
                    CancelIo(pThis->hPipe);
                DWORD cbRead = 0;
                GetOverlappedResult(pThis->hPipe, &pThis->Overlapped, &cbRead, TRUE /*fWait*/);
            }
            if (RT_FAILURE(rc))
                break;
        }
    }

    if (rc == VERR_BROKEN_PIPE)
        pThis->fBrokenPipe = true;

    RTCritSectLeave(&pThis->CritSect);
    return rc;
}