Source code of Windows XP (NT5)
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.

259 lines
5.9 KiB

  1. /**********************************************************************
  2. Copyright (c) 1992-1995 Microsoft Corporation
  3. queue.c
  4. DESCRIPTION:
  5. Priority queue routines.
  6. HISTORY:
  7. 02/22/94 [jimge] created.
  8. *********************************************************************/
  9. #include "preclude.h"
  10. #include <windows.h>
  11. #include <windowsx.h>
  12. #include <mmsystem.h>
  13. #include <mmddk.h>
  14. #include "idf.h"
  15. #include "midimap.h"
  16. #include "debug.h"
  17. //#pragma warning(disable:4704)
  18. /***************************************************************************
  19. @doc internal
  20. @api void | QueueInit | Prepare a queue for use.
  21. @parm PQUEUE | pq | Queue to clear.
  22. ***************************************************************************/
  23. void FNGLOBAL QueueInit(
  24. PQUEUE pq)
  25. {
  26. InitializeCriticalSection (&(pq->cs));
  27. pq->pqeFront = NULL;
  28. pq->pqeRear = NULL;
  29. pq->cEle = 0;
  30. }
  31. /***************************************************************************
  32. @doc internal
  33. @api void | QueueCleanup | Cleans up a queue after use.
  34. @parm PQUEUE | pq | Queue to clear.
  35. ***************************************************************************/
  36. void FNGLOBAL QueueCleanup(
  37. PQUEUE pq)
  38. {
  39. DeleteCriticalSection (&(pq->cs));
  40. pq->pqeFront = NULL;
  41. pq->pqeRear = NULL;
  42. pq->cEle = 0;
  43. }
  44. /***************************************************************************
  45. @doc internal
  46. @api void | QueuePut | Insert an item into the queue.
  47. @parm PQUEUE | pq | Queue to insert into.
  48. @parm PQUEUEELE | pqe | New element to insert.
  49. @parm UINT | uPriority | Priority of the new element.
  50. @comm New elements will be inserted in priority order. Low priorities
  51. go near the front of the queue (first to be dequeued). New elements
  52. will be inserted at the end of all elements in the queue with
  53. equal or lower priorities.
  54. ***************************************************************************/
  55. void FNGLOBAL QueuePut(
  56. PQUEUE pq,
  57. PQUEUEELE pqe,
  58. UINT uPriority)
  59. {
  60. PQUEUEELE pqePrev;
  61. PQUEUEELE pqeCurr;
  62. EnterCriticalSection(&(pq->cs));
  63. pqePrev = NULL;
  64. pqeCurr = pq->pqeFront;
  65. pqe->uPriority = uPriority;
  66. // Position pqePrev and pqeCurr so that pqe should be
  67. // inserted between them.
  68. //
  69. while (NULL != pqeCurr)
  70. {
  71. if (uPriority < pqeCurr->uPriority)
  72. break;
  73. pqePrev = pqeCurr;
  74. pqeCurr = pqeCurr->pqeNext;
  75. }
  76. // Now do the actual insertion.
  77. //
  78. if (NULL == pqePrev)
  79. pq->pqeFront = pqe;
  80. else
  81. pqePrev->pqeNext = pqe;
  82. if (NULL == pqeCurr)
  83. pq->pqeRear = pqe;
  84. else
  85. pqeCurr->pqePrev = pqe;
  86. pqe->pqePrev = pqePrev;
  87. pqe->pqeNext = pqeCurr;
  88. ++pq->cEle;
  89. LeaveCriticalSection(&(pq->cs));
  90. }
  91. /***************************************************************************
  92. @doc internal
  93. @api void | QueueGet | Get and remove the first element from the queue.
  94. @parm PQUEUE | pq | Queue to get the element from.
  95. @rdesc NULL if the queue is empty, otherwise the element pointer.
  96. ***************************************************************************/
  97. PQUEUEELE FNGLOBAL QueueGet(
  98. PQUEUE pq)
  99. {
  100. PQUEUEELE pqe;
  101. EnterCriticalSection(&(pq->cs));
  102. pqe = pq->pqeFront;
  103. if (NULL != pqe)
  104. {
  105. pq->pqeFront = pqe->pqeNext;
  106. if (NULL == pqe->pqeNext)
  107. pq->pqeRear = NULL;
  108. else
  109. pqe->pqeNext->pqePrev = NULL;
  110. pqe->pqePrev = pqe->pqeNext = NULL;
  111. --pq->cEle;
  112. }
  113. LeaveCriticalSection(&(pq->cs));
  114. return pqe;
  115. }
  116. /***************************************************************************
  117. @doc internal
  118. @api void | QueueRemove | Remove a specific element from the queue.
  119. @parm PQUEUE | pq | Queue to remove from.
  120. @parm PQUEUEELE | pqe | Element to remove.
  121. @rdesc TRUE on success, FALSE if the element does not exist in the
  122. queue.
  123. ***************************************************************************/
  124. BOOL FNGLOBAL QueueRemove(
  125. PQUEUE pq,
  126. PQUEUEELE pqe)
  127. {
  128. PQUEUEELE pqeCurr;
  129. EnterCriticalSection(&(pq->cs));
  130. // Ensure that we don't muck around with pointers to some
  131. // other queue.
  132. //
  133. for (pqeCurr = pq->pqeFront; pqeCurr; pqeCurr = pqeCurr->pqeNext)
  134. if (pqe == pqeCurr)
  135. break;
  136. if (NULL == pqeCurr)
  137. {
  138. LeaveCriticalSection(&(pq->cs));
  139. return FALSE;
  140. }
  141. // It's in the queue, remove it.
  142. //
  143. if (NULL == pqe->pqePrev)
  144. pq->pqeFront = pqe->pqeNext;
  145. else
  146. pqe->pqePrev->pqeNext = pqe->pqeNext;
  147. if (NULL == pqe->pqeNext)
  148. pq->pqeRear = pqe->pqePrev;
  149. else
  150. pqe->pqeNext->pqePrev = pqe->pqePrev;
  151. --pq->cEle;
  152. LeaveCriticalSection(&(pq->cs));
  153. return TRUE;
  154. }
  155. /***************************************************************************
  156. @doc internal
  157. @api PQUEUEELE | QueueGetFilter | Remove the first element from a
  158. priority queue which matches a filter.
  159. @parm PQUEUE | pq | Queue to remove from.
  160. @parm FNFILTER | fnf | Filter function. Should return TRUE if
  161. the passed PQUEUEELE matches the filter criteria and should
  162. be removed.
  163. @rdesc A PQUEUEELE or NULL if none are available that match the
  164. filter.
  165. ***************************************************************************/
  166. PQUEUEELE FNGLOBAL QueueGetFilter(
  167. PQUEUE pq,
  168. FNFILTER fnf)
  169. {
  170. PQUEUEELE pqe;
  171. EnterCriticalSection(&(pq->cs));
  172. for (pqe = pq->pqeFront; pqe; pqe = pqe->pqeNext)
  173. if (fnf(pqe))
  174. break;
  175. if (NULL != pqe)
  176. QueueRemove(pq, pqe);
  177. LeaveCriticalSection(&(pq->cs));
  178. return pqe;
  179. }