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.

189 lines
4.3 KiB

  1. /********************************************************************/
  2. /** Microsoft LAN Manager **/
  3. /** Copyright(c) Microsoft Corp., 1990-2000 **/
  4. /********************************************************************/
  5. /* :ts=4 */
  6. #ifndef __QUEUE_H__
  7. #define __QUEUE_H__
  8. //** QUEUE.H - TCP/UDP queuing definitons.
  9. //
  10. // This file contains the definitions for the queue functions used
  11. // by the TCP/UDP code.
  12. //
  13. //* Definition of a queue linkage field.
  14. struct Queue {
  15. struct Queue *q_next;
  16. struct Queue *q_prev;
  17. }; /* Queue */
  18. typedef struct Queue Queue;
  19. //* Initialize queue macro.
  20. #define INITQ(q) { (q)->q_next = (q);\
  21. (q)->q_prev = (q); }
  22. //* Macro to check for queue empty.
  23. #define EMPTYQ(q) ((BOOLEAN)((q)->q_next == (q)))
  24. //* Place an element onto the end of the queue.
  25. #define ENQUEUE(q, e) { (q)->q_prev->q_next = (e);\
  26. (e)->q_prev = (q)->q_prev;\
  27. (q)->q_prev = (e);\
  28. (e)->q_next = (q); }
  29. //* Remove an element from the head of the queue. This macro assumes the queue
  30. // is not empty. The element is returned as type t, queued through linkage
  31. // l.
  32. #define DEQUEUE(q, ptr, t, l) {\
  33. Queue *__tmp__;\
  34. \
  35. __tmp__ = (q)->q_next;\
  36. (q)->q_next = __tmp__->q_next;\
  37. __tmp__->q_next->q_prev = (q);\
  38. (ptr) = STRUCT_OF(t, __tmp__, l);\
  39. }
  40. //* Peek at an element at the head of the queue. We return a pointer to it
  41. // without removing anything.
  42. #define PEEKQ(q, ptr, t, l) {\
  43. Queue *__tmp__;\
  44. \
  45. __tmp__ = (q)->q_next;\
  46. (ptr) = STRUCT_OF(t, __tmp__, l);\
  47. }
  48. //* Macro to push an element onto the head of a queue.
  49. #define PUSHQ(q, e) { (e)->q_next = (q)->q_next;\
  50. (q)->q_next->q_prev = (e);\
  51. (e)->q_prev = (q);\
  52. (q)->q_next = e; }
  53. //* Macro to remove an element from the middle of a queue.
  54. #define REMOVEQ(q) { (q)->q_next->q_prev = (q)->q_prev;\
  55. (q)->q_prev->q_next = (q)->q_next; }
  56. //** The following macros define methods for working with queue without
  57. // dequeueing, mostly dealing with Queue structures directly.
  58. //* Macro to define the end of a Q, used in walking a queue sequentially.
  59. #define QEND(q) (q)
  60. //* Macro to get the first on a queue.
  61. #define QHEAD(q) (q)->q_next
  62. //* Macro to get a structure, given a queue.
  63. #define QSTRUCT(t, q, l) STRUCT_OF(t, (q), l)
  64. //* Macro to get the next thing on q queue.
  65. #define QNEXT(q) (q)->q_next
  66. //* Macro to get the previous thing on q queue.
  67. #define QPREV(q) (q)->q_prev
  68. __inline
  69. VOID
  70. InterlockedEnqueue(
  71. IN Queue* Q,
  72. IN Queue* Item,
  73. IN CTELock* Lock)
  74. {
  75. CTELockHandle Handle;
  76. CTEGetLock(Lock, &Handle);
  77. ENQUEUE(Q, Item);
  78. CTEFreeLock(Lock, Handle);
  79. }
  80. __inline
  81. VOID
  82. InterlockedEnqueueAtDpcLevel(
  83. IN Queue* Q,
  84. IN Queue* Item,
  85. IN CTELock* Lock)
  86. {
  87. CTEGetLockAtDPC(Lock);
  88. ENQUEUE(Q, Item);
  89. CTEFreeLockFromDPC(Lock);
  90. }
  91. __inline
  92. Queue*
  93. InterlockedDequeueIfNotEmpty(
  94. IN Queue* Q,
  95. IN CTELock* Lock)
  96. {
  97. CTELockHandle Handle;
  98. Queue* Item = NULL;
  99. if (!EMPTYQ(Q)) {
  100. CTEGetLock(Lock, &Handle);
  101. if (!EMPTYQ(Q)) {
  102. Item = Q->q_next;
  103. Q->q_next = Item->q_next;
  104. Item->q_next->q_prev = Q;
  105. }
  106. CTEFreeLock(Lock, Handle);
  107. }
  108. return Item;
  109. }
  110. __inline
  111. Queue*
  112. InterlockedDequeueIfNotEmptyAtIrql(
  113. IN Queue* Q,
  114. IN CTELock* Lock,
  115. IN KIRQL OrigIrql)
  116. {
  117. CTELockHandle Handle;
  118. Queue* Item = NULL;
  119. if (!EMPTYQ(Q)) {
  120. CTEGetLockAtIrql(Lock, OrigIrql, &Handle);
  121. if (!EMPTYQ(Q)) {
  122. Item = Q->q_next;
  123. Q->q_next = Item->q_next;
  124. Item->q_next->q_prev = Q;
  125. }
  126. CTEFreeLockAtIrql(Lock, OrigIrql, Handle);
  127. }
  128. return Item;
  129. }
  130. __inline
  131. VOID
  132. InterlockedRemoveQueueItem(
  133. IN Queue* Q,
  134. IN CTELock* Lock)
  135. {
  136. CTELockHandle Handle;
  137. CTEGetLock(Lock, &Handle);
  138. REMOVEQ(Q);
  139. CTEFreeLock(Lock, Handle);
  140. }
  141. __inline
  142. VOID
  143. InterlockedRemoveQueueItemAtDpcLevel(
  144. IN Queue* Q,
  145. IN CTELock* Lock)
  146. {
  147. CTEGetLockAtDPC(Lock);
  148. REMOVEQ(Q);
  149. CTEFreeLockFromDPC(Lock);
  150. }
  151. #endif // __QUEUE_H__