home *** CD-ROM | disk | FTP | other *** search
- //==========================================================================;
- //
- // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
- // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
- // PURPOSE.
- //
- // Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
- //
- //--------------------------------------------------------------------------;
- // SCHEDULE.H
-
- #ifndef __CAMSchedule__
- #define __CAMSchedule__
-
- class CAMSchedule
- {
- public:
- virtual ~CAMSchedule();
- CAMSchedule();
-
- DWORD GetAdviseCount();
- REFERENCE_TIME GetNextAdviseTime();
-
- // We need a method for derived classes to add advise packets, we return the cookie
- DWORD AddAdvisePacket( const REFERENCE_TIME & time1, const REFERENCE_TIME & time2, HANDLE h, BOOL periodic );
- // And a way to cancel
- STDMETHODIMP Unadvise(DWORD 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 );
-
- protected:
- virtual void Dispatch( DWORD Cookie, REFERENCE_TIME & time1, REFERENCE_TIME & time2, HANDLE & h, BOOL & periodic );
-
- 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 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 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 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 AddAdvisePacket( CAdvisePacket * pPacket );
-
- // 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
- #define DumpLinkedList() {}
- #endif
-
- };
-
- #endif // __CAMSchedule__
-