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.

134 lines
5.4 KiB

  1. //-----------------------------------------------------------------------------
  2. //
  3. //
  4. // File: fifoq.h
  5. //
  6. // Description:
  7. // FifoQueue class definition. Provides a high-speed memory
  8. // efficient growable FIFO queue for COM-style objects that
  9. // support addref and release.
  10. //
  11. // Author: mikeswa
  12. //
  13. // Copyright (C) 1997 Microsoft Corporation
  14. //
  15. //-----------------------------------------------------------------------------
  16. #ifndef _FIFOQ_H_
  17. #define _FIFOQ_H_
  18. #include <aqincs.h>
  19. #include <rwnew.h>
  20. #define FIFOQ_SIG 'euQF'
  21. template<class PQDATA>
  22. class CFifoQueuePage;
  23. //---[ CFifoQueue ]------------------------------------------------------------
  24. //
  25. //
  26. // Hungarian: fq, pfq
  27. //
  28. // Implements a FIFO Queue for COM objects (or any objects that supports
  29. // addref and release). Provides the ability to peek, requeue, and maintain a
  30. // cursor into the queue in addition to the normal queue operations.
  31. //
  32. //-----------------------------------------------------------------------------
  33. template<class PQDATA>
  34. class CFifoQueue
  35. {
  36. public:
  37. typedef HRESULT (*MAPFNAPI)(PQDATA, PVOID, BOOL*, BOOL*); //function type for MapFn
  38. CFifoQueue();
  39. ~CFifoQueue();
  40. //static startup and shutdown operations
  41. //These are ref counted and can be called multiple times
  42. //Eventually we might decide to modify the size of the free list based
  43. //on the number of references.
  44. static void StaticInit();
  45. static void StaticDeinit();
  46. //Normal Queue operations
  47. HRESULT HrEnqueue(IN PQDATA pqdata); //Data to enqueue
  48. HRESULT HrDequeue(OUT PQDATA *ppqdata); //Data dequeued
  49. //Insert at the front of the queue
  50. HRESULT HrRequeue(IN PQDATA pqdata); //Data to requeue
  51. //Return the data at the head of the queue without dequeuing
  52. HRESULT HrPeek(OUT PQDATA *ppqdata); //Data peeked
  53. //returns the number of entries in the queue
  54. DWORD cGetCount() {return m_cQueueEntries;};
  55. //Advances the secondary cursor until supplied function returns FALSE
  56. // The pFunc parameter must be a function with the following prototype:
  57. //
  58. // HRESULT pvFunc(
  59. // IN PQDATA pqdata, //ptr to data on queue
  60. // IN PVOID pvContext, //context passed to function
  61. // OUT BOOL *pfContinue, //TRUE if we should continue
  62. // OUT BOOL *pfDelete); //TRUE if item should be deleted
  63. // pFunc must NOT release pqdata.. if it is no longer valid, it should
  64. // return TRUE in pfDelete, and the calling code will remove it from
  65. // the queue and release it.
  66. // NOTE: the MAPFNAPI is CFifoQueue<PQDATA>::MAPFNAPI and is
  67. // specific to the type of template
  68. HRESULT HrMapFn(
  69. IN MAPFNAPI pFunc, //ptr to function to map
  70. IN PVOID pvContext, //context to pass to function
  71. OUT DWORD *pcItems); //number of items mapped
  72. protected:
  73. #ifdef DEBUG
  74. void AssertQueueFn(BOOL fHaveLocks = FALSE);
  75. #endif //DEBUG
  76. typedef CFifoQueuePage<PQDATA> FQPAGE;
  77. DWORD m_dwSignature;
  78. DWORD m_cQueueEntries; //Count of entries in queue
  79. FQPAGE *m_pfqpHead; //First Queue Page
  80. FQPAGE *m_pfqpTail; //Tail Page of queue
  81. FQPAGE *m_pfqpCursor; //Page that the cursor is on
  82. PQDATA *m_ppqdataHead; //Next item to be grabbed
  83. PQDATA *m_ppqdataTail; //First free space available
  84. PQDATA *m_ppqdataCursor; //secondary queue cursor that is
  85. //between the head and the tail
  86. //of the queue
  87. CShareLockNH m_slTail; //CS for updating tail ptr & page
  88. CShareLockNH m_slHead; //CS for updating head ptr & page
  89. //Adjusts head ptr for dequeue and peek
  90. HRESULT HrAdjustHead();
  91. //Static Methods and variables to manage a free list of queue pages
  92. volatile static FQPAGE *s_pfqpFree; //Pointer to free page list
  93. static DWORD s_cFreePages; //Count of pages on free list
  94. static DWORD s_cFifoQueueObj; //Count of queue objects
  95. static DWORD s_cStaticRefs; //# of calls to HrStaticInit
  96. static CRITICAL_SECTION s_csAlloc; //Protect against ABA in alloc
  97. static HRESULT HrAllocQueuePage(
  98. OUT FQPAGE **ppfqp); //allocated page
  99. static void FreeQueuePage(FQPAGE *pfqp);
  100. static void FreeAllQueuePages(); //Free all pages at shutdown
  101. #ifdef DEBUG
  102. //use when making changes to do basic tracking of memory leaks
  103. static DWORD s_cAllocated; //Count of allocated queue pages
  104. static DWORD s_cDeleted; //Count of deleted queue pages
  105. static DWORD s_cFreeAllocated; //allocations from free list
  106. static DWORD s_cFreeDeleted; //number of calls to add to free list
  107. #endif //DEBUG
  108. };
  109. //Example HrMapFn Function that will clear the queue.
  110. template <class PQDATA>
  111. HRESULT HrClearQueueMapFn(IN PQDATA pqdata, OUT BOOL *pfContinue, OUT BOOL *pfDelete);
  112. #endif // _FIFOQ_H_