schedule.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. //------------------------------------------------------------------------------
  2. // File: Schedule.h
  3. //
  4. // Desc: DirectShow base classes.
  5. //
  6. // Copyright (c) 1996-2001 Microsoft Corporation. All rights reserved.
  7. //------------------------------------------------------------------------------
  8. #ifndef __CAMSchedule__
  9. #define __CAMSchedule__
  10. class CAMSchedule : private CBaseObject
  11. {
  12. public:
  13. virtual ~CAMSchedule();
  14. // ev is the event we should fire if the advise time needs re-evaluating
  15. CAMSchedule( HANDLE ev );
  16. DWORD GetAdviseCount();
  17. REFERENCE_TIME GetNextAdviseTime();
  18. // We need a method for derived classes to add advise packets, we return the cookie
  19. DWORD_PTR AddAdvisePacket( const REFERENCE_TIME & time1, const REFERENCE_TIME & time2, HANDLE h, BOOL periodic );
  20. // And a way to cancel
  21. HRESULT Unadvise(DWORD_PTR dwAdviseCookie);
  22. // Tell us the time please, and we'll dispatch the expired events. We return the time of the next event.
  23. // NB: The time returned will be "useless" if you start adding extra Advises. But that's the problem of
  24. // whoever is using this helper class (typically a clock).
  25. REFERENCE_TIME Advise( const REFERENCE_TIME & rtTime );
  26. // Get the event handle which will be set if advise time requires re-evaluation.
  27. HANDLE GetEvent() const {
  28. return m_ev;
  29. }
  30. private:
  31. // We define the nodes that will be used in our singly linked list
  32. // of advise packets. The list is ordered by time, with the
  33. // elements that will expire first at the front.
  34. class CAdvisePacket
  35. {
  36. public:
  37. CAdvisePacket() {
  38. }
  39. CAdvisePacket * m_next;
  40. DWORD_PTR m_dwAdviseCookie;
  41. REFERENCE_TIME m_rtEventTime; // Time at which event should be set
  42. REFERENCE_TIME m_rtPeriod; // Periodic time
  43. HANDLE m_hNotify; // Handle to event or semephore
  44. BOOL m_bPeriodic; // TRUE => Periodic event
  45. CAdvisePacket( __inout_opt CAdvisePacket * next, LONGLONG time ) : m_next(next), m_rtEventTime(time) {
  46. }
  47. void InsertAfter( __inout CAdvisePacket * p ) {
  48. p->m_next = m_next;
  49. m_next = p;
  50. }
  51. int IsZ() const { // That is, is it the node that represents the end of the list
  52. return m_next == 0;
  53. }
  54. CAdvisePacket * RemoveNext() {
  55. CAdvisePacket *const next = m_next;
  56. CAdvisePacket *const new_next = next->m_next;
  57. m_next = new_next;
  58. return next;
  59. }
  60. void DeleteNext() {
  61. delete RemoveNext();
  62. }
  63. CAdvisePacket * Next() const {
  64. CAdvisePacket * result = m_next;
  65. if (result->IsZ()) {
  66. result = 0;
  67. }
  68. return result;
  69. }
  70. DWORD_PTR Cookie() const {
  71. return m_dwAdviseCookie;
  72. }
  73. };
  74. // Structure is:
  75. // head -> elmt1 -> elmt2 -> z -> null
  76. // So an empty list is: head -> z -> null
  77. // Having head & z as links makes insertaion,
  78. // deletion and shunting much easier.
  79. CAdvisePacket head, z; // z is both a tail and a sentry
  80. volatile DWORD_PTR m_dwNextCookie; // Strictly increasing
  81. volatile DWORD m_dwAdviseCount; // Number of elements on list
  82. CCritSec m_Serialize;
  83. // AddAdvisePacket: adds the packet, returns the cookie (0 if failed)
  84. DWORD_PTR AddAdvisePacket( __inout CAdvisePacket * pPacket );
  85. // Event that we should set if the packed added above will be the next to fire.
  86. const HANDLE m_ev;
  87. // A Shunt is where we have changed the first element in the
  88. // list and want it re-evaluating (i.e. repositioned) in
  89. // the list.
  90. void ShuntHead();
  91. // Rather than delete advise packets, we cache them for future use
  92. CAdvisePacket * m_pAdviseCache;
  93. DWORD m_dwCacheCount;
  94. enum { dwCacheMax = 5 }; // Don't bother caching more than five
  95. void Delete( __inout CAdvisePacket * pLink );// This "Delete" will cache the Link
  96. // Attributes and methods for debugging
  97. public:
  98. #ifdef DEBUG
  99. void DumpLinkedList();
  100. #else
  101. void DumpLinkedList() {}
  102. #endif
  103. };
  104. #endif // __CAMSchedule__