//------------------------------------------------------------------------------
// File: Schedule.cpp
//
// Desc: DirectShow base classes.
//
// Copyright (c) 1996-2001 Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------------------------


#include <streams.h>

// DbgLog values (all on LOG_TIMING):
//
// 2 for schedulting, firing and shunting of events
// 3 for wait delays and wake-up times of event thread
// 4 for details of whats on the list when the thread awakes

/* Construct & destructors */

CAMSchedule::CAMSchedule( HANDLE ev )
: CBaseObject(TEXT("CAMSchedule"))
, head(&z, 0), z(0, MAX_TIME)
, m_dwNextCookie(0), m_dwAdviseCount(0)
, m_pAdviseCache(0), m_dwCacheCount(0)
, m_ev( ev )
{
    head.m_dwAdviseCookie = z.m_dwAdviseCookie = 0;
}

CAMSchedule::~CAMSchedule()
{
    m_Serialize.Lock();

    // Delete cache
    CAdvisePacket * p = m_pAdviseCache;
    while (p)
    {
        CAdvisePacket *const p_next = p->m_next;
        delete p;
        p = p_next;
    }

    ASSERT( m_dwAdviseCount == 0 );
    // Better to be safe than sorry
    if ( m_dwAdviseCount > 0 )
    {
        DumpLinkedList();
        while ( !head.m_next->IsZ() )
        {
            head.DeleteNext();
            --m_dwAdviseCount;
        }
    }

    // If, in the debug version, we assert twice, it means, not only
    // did we have left over advises, but we have also let m_dwAdviseCount
    // get out of sync. with the number of advises actually on the list.
    ASSERT( m_dwAdviseCount == 0 );

    m_Serialize.Unlock();
}

/* Public methods */

DWORD CAMSchedule::GetAdviseCount()
{
    // No need to lock, m_dwAdviseCount is 32bits & declared volatile
    return m_dwAdviseCount;
}

REFERENCE_TIME CAMSchedule::GetNextAdviseTime()
{
    CAutoLock lck(&m_Serialize); // Need to stop the linked list from changing
    return head.m_next->m_rtEventTime;
}

DWORD_PTR CAMSchedule::AddAdvisePacket
( const REFERENCE_TIME & time1
, const REFERENCE_TIME & time2
, HANDLE h, BOOL periodic
)
{
    // Since we use MAX_TIME as a sentry, we can't afford to
    // schedule a notification at MAX_TIME
    ASSERT( time1 < MAX_TIME );
    DWORD_PTR Result;
    CAdvisePacket * p;

    m_Serialize.Lock();

    if (m_pAdviseCache)
    {
        p = m_pAdviseCache;
        m_pAdviseCache = p->m_next;
        --m_dwCacheCount;
    }
    else
    {
        p = new CAdvisePacket();
    }
    if (p)
    {
        p->m_rtEventTime = time1; p->m_rtPeriod = time2;
        p->m_hNotify = h; p->m_bPeriodic = periodic;
        Result = AddAdvisePacket( p );
    }
    else Result = 0;

    m_Serialize.Unlock();

    return Result;
}

HRESULT CAMSchedule::Unadvise(DWORD_PTR dwAdviseCookie)
{
    HRESULT hr = S_FALSE;
    CAdvisePacket * p_prev = &head;
    CAdvisePacket * p_n;
    m_Serialize.Lock();
    while ( p_n = p_prev->Next() ) // The Next() method returns NULL when it hits z
    {
        if ( p_n->m_dwAdviseCookie == dwAdviseCookie )
        {
            Delete( p_prev->RemoveNext() );
            --m_dwAdviseCount;
            hr = S_OK;
	    // Having found one cookie that matches, there should be no more
            #ifdef DEBUG
	       while (p_n = p_prev->Next())
               {
                   ASSERT(p_n->m_dwAdviseCookie != dwAdviseCookie);
                   p_prev = p_n;
               }
            #endif
            break;
        }
        p_prev = p_n;
    };
    m_Serialize.Unlock();
    return hr;
}

REFERENCE_TIME CAMSchedule::Advise( const REFERENCE_TIME & rtTime )
{
    REFERENCE_TIME  rtNextTime;
    CAdvisePacket * pAdvise;

    DbgLog((LOG_TIMING, 2,
        TEXT("CAMSchedule::Advise( %lu ms )"), ULONG(rtTime / (UNITS / MILLISECONDS))));

    CAutoLock lck(&m_Serialize);

    #ifdef DEBUG
        if (DbgCheckModuleLevel(LOG_TIMING, 4)) DumpLinkedList();
    #endif

    //  Note - DON'T cache the difference, it might overflow 
    while ( rtTime >= (rtNextTime = (pAdvise=head.m_next)->m_rtEventTime) &&
            !pAdvise->IsZ() )
    {
        ASSERT(pAdvise->m_dwAdviseCookie); // If this is zero, its the head or the tail!!

        ASSERT(pAdvise->m_hNotify != INVALID_HANDLE_VALUE);

        if (pAdvise->m_bPeriodic == TRUE)
        {
            ReleaseSemaphore(pAdvise->m_hNotify,1,NULL);
            pAdvise->m_rtEventTime += pAdvise->m_rtPeriod;
            ShuntHead();
        }
        else
        {
            ASSERT( pAdvise->m_bPeriodic == FALSE );
            EXECUTE_ASSERT(SetEvent(pAdvise->m_hNotify));
            --m_dwAdviseCount;
            Delete( head.RemoveNext() );
        }

    }

    DbgLog((LOG_TIMING, 3,
            TEXT("CAMSchedule::Advise() Next time stamp: %lu ms, for advise %lu."),
            DWORD(rtNextTime / (UNITS / MILLISECONDS)), pAdvise->m_dwAdviseCookie ));

    return rtNextTime;
}

/* Private methods */

DWORD_PTR CAMSchedule::AddAdvisePacket( __inout CAdvisePacket * pPacket )
{
    ASSERT(pPacket->m_rtEventTime >= 0 && pPacket->m_rtEventTime < MAX_TIME);
    ASSERT(CritCheckIn(&m_Serialize));

    CAdvisePacket * p_prev = &head;
    CAdvisePacket * p_n;

    const DWORD_PTR Result = pPacket->m_dwAdviseCookie = ++m_dwNextCookie;
    // This relies on the fact that z is a sentry with a maximal m_rtEventTime
    for(;;p_prev = p_n)
    {
        p_n = p_prev->m_next;
        if ( p_n->m_rtEventTime >= pPacket->m_rtEventTime ) break;
    }
    p_prev->InsertAfter( pPacket );
    ++m_dwAdviseCount;

    DbgLog((LOG_TIMING, 2, TEXT("Added advise %lu, for thread 0x%02X, scheduled at %lu"),
    	pPacket->m_dwAdviseCookie, GetCurrentThreadId(), (pPacket->m_rtEventTime / (UNITS / MILLISECONDS)) ));

    // If packet added at the head, then clock needs to re-evaluate wait time.
    if ( p_prev == &head ) SetEvent( m_ev );

    return Result;
}

void CAMSchedule::Delete( __inout CAdvisePacket * pPacket )
{
    if ( m_dwCacheCount >= dwCacheMax ) delete pPacket;
    else
    {
        m_Serialize.Lock();
        pPacket->m_next = m_pAdviseCache;
        m_pAdviseCache = pPacket;
        ++m_dwCacheCount;
        m_Serialize.Unlock();
    }
}


// Takes the head of the list & repositions it
void CAMSchedule::ShuntHead()
{
    CAdvisePacket * p_prev = &head;
    CAdvisePacket * p_n;

    m_Serialize.Lock();
    CAdvisePacket *const pPacket = head.m_next;

    // This will catch both an empty list,
    // and if somehow a MAX_TIME time gets into the list
    // (which would also break this method).
    ASSERT( pPacket->m_rtEventTime < MAX_TIME );

    // This relies on the fact that z is a sentry with a maximal m_rtEventTime
    for(;;p_prev = p_n)
    {
        p_n = p_prev->m_next;
        if ( p_n->m_rtEventTime > pPacket->m_rtEventTime ) break;
    }
    // If p_prev == pPacket then we're already in the right place
    if (p_prev != pPacket)
    {
        head.m_next = pPacket->m_next;
        (p_prev->m_next = pPacket)->m_next = p_n;
    }
    #ifdef DEBUG
        DbgLog((LOG_TIMING, 2, TEXT("Periodic advise %lu, shunted to %lu"),
    	    pPacket->m_dwAdviseCookie, (pPacket->m_rtEventTime / (UNITS / MILLISECONDS)) ));
    #endif
    m_Serialize.Unlock();
}


#ifdef DEBUG
void CAMSchedule::DumpLinkedList()
{
    m_Serialize.Lock();
    int i=0;
    DbgLog((LOG_TIMING, 1, TEXT("CAMSchedule::DumpLinkedList() this = 0x%p"), this));
    for ( CAdvisePacket * p = &head
        ; p
        ; p = p->m_next         , i++
        )	
    {
        DbgLog((LOG_TIMING, 1, TEXT("Advise List # %lu, Cookie %d,  RefTime %lu"),
            i,
	    p->m_dwAdviseCookie,
	    p->m_rtEventTime / (UNITS / MILLISECONDS)
            ));
    }
    m_Serialize.Unlock();
}
#endif
