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.

342 lines
8.7 KiB

  1. #ifndef _SIMPLE_QUEUE_H
  2. #define _SIMPLE_QUEUE_H 1
  3. /*++
  4. Copyright (c) 1996 Microsoft Corporation
  5. Module Name:
  6. simpleq.h
  7. Abstract:
  8. Simple non-blocking queue, that allows
  9. multiple concurrent data providers
  10. and singe data consumer
  11. Author:
  12. GorN 9-Feb-1999
  13. Revision History:
  14. --*/
  15. #define COUNT_DROPPED_PACKETS 1 // Enable dropped packet counting
  16. // The queue can store blocks of variable sizes
  17. // each block is prefixed by this structure
  18. typedef struct _SIMPLEQUEUE_BLOCK_HEADER
  19. {
  20. DWORD PayloadSize; // this is the size of the block
  21. // as it was passed to us by the client
  22. }
  23. SIMPLEQUEUE_BLOCK_HEADER, *PSIMPLEQUEUE_BLOCK_HEADER;
  24. #define SQB_ALIGNMENT ( sizeof(DWORD) )
  25. #define SQB_INFLATE_SIZE( size )( (size + SQB_ALIGNMENT - 1) & ~(SQB_ALIGNMENT - 1) )
  26. #define SQB_PAYLOADSIZE_TO_BLOCKSIZE( size )( SQB_INFLATE_SIZE(size + sizeof(SIMPLEQUEUE_BLOCK_HEADER)) )
  27. #define SQB_HEADER( ptr ) ( (PSIMPLEQUEUE_BLOCK_HEADER)(ptr) )
  28. #define SQB_PAYLOADSIZE( ptr ) ( SQB_HEADER(ptr)->PayloadSize )
  29. #define SQB_BLOCKSIZE( ptr ) ( SQB_PAYLOADSIZE_TO_BLOCKSIZE( SQB_PAYLOADSIZE( ptr ) ) )
  30. #define SQB_NEXTBLOCK( ptr ) ( (PVOID)( (PUCHAR)(ptr) + SQB_BLOCKSIZE( ptr ) ) )
  31. #define SQB_PAYLOAD( ptr ) ( (PVOID)(SQB_HEADER(ptr) + 1) )
  32. typedef struct _SIMPLEQUEUE *PSIMPLEQUEUE;
  33. // The following function will be called if there are dropped data and
  34. // the last time we reported dropped data was NotifyInterval
  35. // or more seconds before.
  36. typedef void (*DROPPED_DATA_NOTIFY) (
  37. IN PWCHAR QueueName,
  38. IN DWORD DroppedDataCount,
  39. IN DWORD DroppedDataSize);
  40. // The following function will be called if there are data available
  41. // in the queue. It will not be called again until
  42. // Read/CompleteRead operations empty the queue.
  43. typedef void (*DATA_AVAILABLE_CALLBACK)(
  44. IN PSIMPLEQUEUE q);
  45. DWORD SimpleQueueInitialize(
  46. IN OUT PSIMPLEQUEUE q,
  47. IN DWORD cbSize,
  48. IN PWCHAR Name,
  49. IN DATA_AVAILABLE_CALLBACK DataAvailableCallback,
  50. IN DROPPED_DATA_NOTIFY DroppedDataNotifyCallback,
  51. IN DWORD NotifyInterval // in seconds //
  52. );
  53. /*++
  54. Routine Description:
  55. Initializes a queue
  56. Arguments:
  57. q - a queue to be initialized
  58. cbSize - size of the queue in bytes
  59. Name - Name of the queue. It will be supplied to DroppedDataNotifyCallback
  60. DataAvailableCallback - This function will be called if there are data available
  61. in the queue. This function will not be called again until
  62. Read/CompleteRead operations empty the queue.
  63. DroppedDataNotifyCallback - This function will be called if there are dropped data and
  64. the last time we reported dropped data was NotifyInterval
  65. or more seconds before.
  66. NotifyInterval - We will not report dropped data unless it has been longer
  67. than NotifyInterval seconds since the last report
  68. Return Value:
  69. ERROR_SUCCESS - success
  70. error code - called failed
  71. */
  72. VOID
  73. SimpleQueueDelete(
  74. IN PSIMPLEQUEUE q
  75. );
  76. /*++
  77. Routine Description:
  78. Destroys a queue
  79. Arguments:
  80. q - a queue to be destroyed
  81. Return Value:
  82. None
  83. Comments:
  84. This routine will destroy queue's CriticalSection
  85. and deallocate queue's memory. It is the responsibility of
  86. the caller to guarantee that nobody will be using the queue
  87. after this function is called
  88. */
  89. BOOL
  90. SimpleQueueTryAdd(
  91. IN PSIMPLEQUEUE q,
  92. IN DWORD PayloadSize,
  93. IN PVOID Payload
  94. );
  95. /*++
  96. Routine Description:
  97. Tries to add data in a queue
  98. Arguments:
  99. q - a queue
  100. PayloadSise - size of the chunk to be added to a queue
  101. Payload - pointer to a buffer that countains data to be added
  102. Return Value:
  103. TRUE - if the data were put into the queue successfully
  104. FALSE - otherwise
  105. Comments:
  106. DataAvailableCallback will be called
  107. if there are data available. DataAvailableCallback will not be called
  108. during subsequent add requests until Read/CompleteRead
  109. operations empty the queue.
  110. */
  111. BOOL
  112. SimpleQueueReadAll(
  113. IN PSIMPLEQUEUE q,
  114. OUT PVOID* begin,
  115. OUT PVOID* end
  116. );
  117. /*++
  118. Routine Description:
  119. Allows to read all available blocks
  120. Arguments:
  121. q - a queue
  122. begin - receives a pointer to the first queue block
  123. end - receives a pointer past the end of the last queue block
  124. Return Value:
  125. TRUE - if we get at least one block
  126. FALSE - if the queue is empty
  127. Comments:
  128. This function not always give you ALL available blocks in the
  129. queue. It gives you all blocks up until the hard end of the queue buffer or
  130. the writing head of the queue, whatever is smaller.
  131. If the function returns success, it guarantees that begin < end.
  132. When you finished processing of the data, you need to call
  133. SimpleQueueReadComplete function.
  134. You can walk over these block using SQB_NEXTBLOCK macro.
  135. */
  136. BOOL
  137. SimpleQueueReadOne(
  138. IN PSIMPLEQUEUE q,
  139. OUT PVOID* begin,
  140. OUT PVOID* end
  141. );
  142. /*++
  143. Routine Description:
  144. Allows to read a single block of data
  145. Arguments:
  146. q - a queue
  147. begin - receives a pointer to the beginning of the first available queue block
  148. end - receives a pointer past the end of this block
  149. Return Value:
  150. TRUE - success
  151. FALSE - if the queue is empty
  152. Comments:
  153. When you finished processing of the data, you need to call
  154. SimpleQueueReadComplete function.
  155. */
  156. BOOL
  157. SimpleQueueReadComplete(
  158. IN PSIMPLEQUEUE q,
  159. IN PVOID newtail
  160. );
  161. /*++
  162. Routine Description:
  163. Use this function to signal that the block of data was
  164. consumed
  165. Arguments:
  166. q - a queue
  167. end - receives a pointer past the end of the last consumed block.
  168. Usually this is a value returned by the PVOID end parameter of
  169. ReadOne and ReadAll
  170. Return Value:
  171. TRUE - There are more data
  172. FALSE - if the queue is empty
  173. Important!!!
  174. If the result of this function is TRUE, the caller should consume the data
  175. using ReadOne or ReadAll functions followed by the calls
  176. to ReadComplete until it returns FALSE.
  177. Otherwise, no futher DataAvailable notifications will be produced bu
  178. SimpleQueueTryAdd
  179. */
  180. #ifdef COUNT_DROPPED_PACKETS
  181. VOID
  182. CheckForDroppedData(
  183. IN PSIMPLEQUEUE q,
  184. IN BOOL Now
  185. );
  186. /*++
  187. Routine Description:
  188. This function checks whether there were
  189. some data dropped and if the time is right,
  190. calls DropNotifyCallback function.
  191. Arguments:
  192. q - a queue
  193. Now - If TRUE, than DropNotifyCallback will be called
  194. immediately if there are dropped data.
  195. If FALSE, DropNotifyCallback will be called
  196. only if it is more then DroppedNotifyInterval
  197. seconds elapsed, since the last time we called
  198. DropNotifyCallback
  199. Return Value:
  200. None
  201. */
  202. #else
  203. #define CheckForDroppedData(x,y)
  204. #endif
  205. typedef struct _SIMPLEQUEUE {
  206. CRITICAL_SECTION Lock;
  207. PWCHAR Name; // arbitrary string
  208. PUCHAR Begin; // queue buffer start
  209. PUCHAR End; // queue buffer end
  210. PUCHAR Head; // writing head
  211. PUCHAR Tail; // consuming end
  212. PUCHAR Wrap; // wrap == 0, if tail < head
  213. // otherwise if it points past the end of
  214. // the last block before queue buffer end
  215. BOOL Empty; // This flag is properly maintained by the queue,
  216. // but not required for the queue to operate
  217. // Can be removed if nobody needs it
  218. BOOL Enabled; // Add operation to the queue will fail
  219. // if the enabled flag is not set
  220. UINT32 ReadInProgress; // DataAvailableCallback notification
  221. // was issued and processing is not
  222. // complete.
  223. //
  224. // This flag is reset by ReadComplete
  225. // when there are no more data
  226. DATA_AVAILABLE_CALLBACK DataAvailableCallback;
  227. #ifdef COUNT_DROPPED_PACKETS
  228. ULARGE_INTEGER NextDroppedDataNotify;
  229. DROPPED_DATA_NOTIFY DroppedDataNotifyCallback;
  230. ULARGE_INTEGER DroppedDataNotifyInterval;
  231. DWORD DroppedDataCount; // These two variable are reset each time
  232. DWORD DroppedDataSize; // we call DroppedDataNotifyCallback
  233. #endif
  234. //
  235. } SIMPLEQUEUE;
  236. #endif