Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
//------------------------------------------------------------------------------
// File: Schedule.h
//
// Desc: DirectShow base classes.
//
// Copyright (c) 1996-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __CAMSchedule__
#define __CAMSchedule__
class CAMSchedule : private CBaseObject { public: virtual ~CAMSchedule(); // ev is the event we should fire if the advise time needs re-evaluating
CAMSchedule( HANDLE ev );
DWORD GetAdviseCount(); REFERENCE_TIME GetNextAdviseTime();
// We need a method for derived classes to add advise packets, we return the cookie
DWORD_PTR AddAdvisePacket( const REFERENCE_TIME & time1, const REFERENCE_TIME & time2, HANDLE h, BOOL periodic ); // And a way to cancel
HRESULT Unadvise(DWORD_PTR dwAdviseCookie);
// Tell us the time please, and we'll dispatch the expired events. We return the time of the next event.
// NB: The time returned will be "useless" if you start adding extra Advises. But that's the problem of
// whoever is using this helper class (typically a clock).
REFERENCE_TIME Advise( const REFERENCE_TIME & rtTime );
// Get the event handle which will be set if advise time requires re-evaluation.
HANDLE GetEvent() const { return m_ev; }
private: // We define the nodes that will be used in our singly linked list
// of advise packets. The list is ordered by time, with the
// elements that will expire first at the front.
class CAdvisePacket { public: CAdvisePacket() {}
CAdvisePacket * m_next; DWORD_PTR m_dwAdviseCookie; REFERENCE_TIME m_rtEventTime; // Time at which event should be set
REFERENCE_TIME m_rtPeriod; // Periodic time
HANDLE m_hNotify; // Handle to event or semephore
BOOL m_bPeriodic; // TRUE => Periodic event
CAdvisePacket( CAdvisePacket * next, LONGLONG time ) : m_next(next), m_rtEventTime(time) {}
void InsertAfter( CAdvisePacket * p ) { p->m_next = m_next; m_next = p; }
int IsZ() const // That is, is it the node that represents the end of the list
{ return m_next == 0; }
CAdvisePacket * RemoveNext() { CAdvisePacket *const next = m_next; CAdvisePacket *const new_next = next->m_next; m_next = new_next; return next; }
void DeleteNext() { delete RemoveNext(); }
CAdvisePacket * Next() const { CAdvisePacket * result = m_next; if (result->IsZ()) result = 0; return result; }
DWORD_PTR Cookie() const { return m_dwAdviseCookie; } };
// Structure is:
// head -> elmt1 -> elmt2 -> z -> null
// So an empty list is: head -> z -> null
// Having head & z as links makes insertaion,
// deletion and shunting much easier.
CAdvisePacket head, z; // z is both a tail and a sentry
volatile DWORD_PTR m_dwNextCookie; // Strictly increasing
volatile DWORD m_dwAdviseCount; // Number of elements on list
CCritSec m_Serialize;
// AddAdvisePacket: adds the packet, returns the cookie (0 if failed)
DWORD_PTR AddAdvisePacket( CAdvisePacket * pPacket ); // Event that we should set if the packed added above will be the next to fire.
const HANDLE m_ev;
// A Shunt is where we have changed the first element in the
// list and want it re-evaluating (i.e. repositioned) in
// the list.
void ShuntHead();
// Rather than delete advise packets, we cache them for future use
CAdvisePacket * m_pAdviseCache; DWORD m_dwCacheCount; enum { dwCacheMax = 5 }; // Don't bother caching more than five
void Delete( CAdvisePacket * pLink );// This "Delete" will cache the Link
// Attributes and methods for debugging
public: #ifdef DEBUG
void DumpLinkedList(); #else
void DumpLinkedList() {} #endif
};
#endif // __CAMSchedule__
|