STDMETHODIMP CBaseReferenceClock::GetTime(REFERENCE_TIME *pTime)
{
    HRESULT hr;
    if (pTime)
    {
        REFERENCE_TIME rtNow;
        Lock();
        rtNow = GetPrivateTime();
        if (rtNow > m_rtLastGotTime)
        {
            m_rtLastGotTime = rtNow;
            hr = S_OK;
        }
        else
        {
            hr = S_FALSE;
        }
        *pTime = m_rtLastGotTime;
        Unlock();
        MSR_INTEGER(m_idGetSystemTime, LONG((*pTime) / (UNITS/MILLISECONDS)) );
    }
    else hr = E_POINTER;

    return hr;
}
Example #2
0
STDMETHODIMP CBaseReferenceClock::GetTime(__out REFERENCE_TIME *pTime)
{
    HRESULT hr;
    if (pTime)
    {
        REFERENCE_TIME rtNow;
        Lock();
        rtNow = GetPrivateTime();
        if (rtNow > m_rtLastGotTime)
        {
            m_rtLastGotTime = rtNow;
            hr = S_OK;
        }
        else
        {
            hr = S_FALSE;
        }
        *pTime = m_rtLastGotTime;
        Unlock();
        MSR_INTEGER(m_idGetSystemTime, LONG((*pTime) / (UNITS/MILLISECONDS)) );

#ifdef DXMPERF
        PERFLOG_GETTIME( (IReferenceClock *) this, *pTime );
#endif // DXMPERF

    }
    else hr = E_POINTER;

    return hr;
}
HRESULT CBaseReferenceClock::AdviseThread()
{
    DWORD dwWait = INFINITE;

    // The first thing we do is wait until something interesting happens
    // (meaning a first advise or shutdown).  This prevents us calling
    // GetPrivateTime immediately which is goodness as that is a virtual
    // routine and the derived class may not yet be constructed.  (This
    // thread is created in the base class constructor.)

    while ( !m_bAbort )
    {
        // Wait for an interesting event to happen
        DbgLog((LOG_TIMING, 3, TEXT("CBaseRefClock::AdviseThread() Delay: %lu ms"), dwWait ));
        WaitForSingleObject(m_pSchedule->GetEvent(), dwWait);
        if (m_bAbort) break;

        // There are several reasons why we need to work from the internal
        // time, mainly to do with what happens when time goes backwards.
        // Mainly, it stop us looping madly if an event is just about to
        // expire when the clock goes backward (i.e. GetTime stop for a
        // while).
        const REFERENCE_TIME  rtNow = GetPrivateTime();

        DbgLog((LOG_TIMING, 3,
              TEXT("CBaseRefClock::AdviseThread() Woke at = %lu ms"),
              ConvertToMilliseconds(rtNow) ));

        // We must add in a millisecond, since this is the resolution of our
        // WaitForSingleObject timer.  Failure to do so will cause us to loop
        // franticly for (approx) 1 a millisecond.
        m_rtNextAdvise = m_pSchedule->Advise( 10000 + rtNow );
        LONGLONG llWait = m_rtNextAdvise - rtNow;

        ASSERT( llWait > 0 );

        llWait = ConvertToMilliseconds(llWait);
        // DON'T replace this with a max!! (The type's of these things is VERY important)
        dwWait = (llWait > REFERENCE_TIME(UINT_MAX)) ? UINT_MAX : DWORD(llWait);
    };
    return NOERROR;
}