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.

362 lines
6.5 KiB

  1. /*++
  2. Copyright (c) 1998-2000 Microsoft Corporation
  3. Module Name:
  4. w32dispq.cpp
  5. Abstract:
  6. Contains the Win32 Operation Dispatch Object class,
  7. W32DispatchQueue.
  8. Enqueue at the head. Dequeue at the tail.
  9. Author:
  10. Tad Brockway (tadb) 4/19/99
  11. Revision History:
  12. --*/
  13. #include <precom.h>
  14. #define TRC_FILE "W32DispQ"
  15. #include "w32dispq.h"
  16. #include "drdbg.h"
  17. ///////////////////////////////////////////////////////////////
  18. //
  19. // W32DispatchQueue Methods
  20. //
  21. //
  22. W32DispatchQueue::W32DispatchQueue()
  23. /*++
  24. Routine Description:
  25. Constructor
  26. Arguments:
  27. initialSize - Initial number of elements in the queue.
  28. Return Value:
  29. NA
  30. --*/
  31. {
  32. DC_BEGIN_FN("W32DispatchQueue::W32DispatchQueue");
  33. //
  34. // Not valid until initialized.
  35. //
  36. SetValid(FALSE);
  37. DC_END_FN();
  38. }
  39. W32DispatchQueue::~W32DispatchQueue()
  40. /*++
  41. Routine Description:
  42. Destructor
  43. Arguments:
  44. NA
  45. Return Value:
  46. NA
  47. --*/
  48. {
  49. DC_BEGIN_FN("W32DispatchQueue::~W32DispatchQueue");
  50. //
  51. // Assert that the queue is empty.
  52. //
  53. ASSERT(_queue->GetCount() == 0);
  54. //
  55. // Release the "data ready" event.
  56. //
  57. if (_dataReadyEvent != NULL) {
  58. CloseHandle(_dataReadyEvent);
  59. }
  60. //
  61. // Release the queue instance.
  62. //
  63. if (_queue != NULL) {
  64. delete _queue;
  65. }
  66. DC_END_FN();
  67. }
  68. DWORD W32DispatchQueue::Initialize()
  69. /*++
  70. Routine Description:
  71. Initialize
  72. Arguments:
  73. Return Value:
  74. ERROR_SUCCESS on success. Otherwise, an error code is returned.
  75. --*/
  76. {
  77. DWORD result = ERROR_SUCCESS;
  78. DC_BEGIN_FN("W32DispatchQueue::Initialize");
  79. //
  80. // Create the "data ready" event.
  81. //
  82. _dataReadyEvent = CreateEvent(
  83. NULL, // no attribute.
  84. FALSE, // auto reset.
  85. FALSE, // initially not signalled.
  86. NULL // no name.
  87. );
  88. if (_dataReadyEvent == NULL) {
  89. result = GetLastError();
  90. TRC_ERR((TB, _T("CreateEvent %ld."), result));
  91. goto CLEANUPANDEXIT;
  92. }
  93. //
  94. // Create the queue instance.
  95. //
  96. _queue = new DrQueue<QUEUEELEMENT>;
  97. if (_queue == NULL) {
  98. TRC_ERR((TB, _T("Can't instantiate DrQueue.")));
  99. result = ERROR_NOT_ENOUGH_MEMORY;
  100. goto CLEANUPANDEXIT;
  101. }
  102. result = _queue->Initialize();
  103. if (result != ERROR_SUCCESS) {
  104. delete _queue;
  105. _queue = NULL;
  106. goto CLEANUPANDEXIT;
  107. }
  108. SetValid(TRUE);
  109. CLEANUPANDEXIT:
  110. return result;
  111. }
  112. BOOL W32DispatchQueue::PeekNextEntry(
  113. OPTIONAL OUT W32DispatchQueueFunc *func,
  114. OPTIONAL OUT VOID **clientData
  115. )
  116. /*++
  117. Routine Description:
  118. Peek at the next entry in the queue without dequeueing.
  119. Arguments:
  120. func - Function associated with next element.
  121. clientData - Client data associated with next element.
  122. Return Value:
  123. NA
  124. --*/
  125. {
  126. BOOL result;
  127. QUEUEELEMENT queueElement;
  128. DC_BEGIN_FN("W32DispatchQueue::PeekNextEntry");
  129. ASSERT(IsValid());
  130. result = IsValid() && _queue->PeekNextEntry(queueElement);
  131. if (result) {
  132. if (func != NULL) {
  133. *func = queueElement.func;
  134. }
  135. if (clientData != NULL) {
  136. *clientData = queueElement.clientData;
  137. }
  138. }
  139. DC_END_FN();
  140. return result;
  141. }
  142. BOOL W32DispatchQueue::Dequeue(
  143. OPTIONAL OUT W32DispatchQueueFunc *func,
  144. OPTIONAL OUT VOID **clientData
  145. )
  146. /*++
  147. Routine Description:
  148. Grab the next queued operation out of the queue.
  149. Arguments:
  150. func - Function associated with next element.
  151. clientData - Client data associated with next element.
  152. Return Value:
  153. TRUE if there was an element in the queue to be dequeued.
  154. --*/
  155. {
  156. BOOL result;
  157. QUEUEELEMENT element;
  158. DC_BEGIN_FN("W32DispatchQueue::Dequeue");
  159. ASSERT(IsValid());
  160. result = IsValid() && _queue->Dequeue(element);
  161. if (result) {
  162. if (func != NULL) *func = element.func;
  163. if (clientData != NULL) *clientData = element.clientData;
  164. }
  165. DC_END_FN();
  166. return result;
  167. }
  168. BOOL W32DispatchQueue::Enqueue(
  169. IN W32DispatchQueueFunc func,
  170. OPTIONAL IN VOID *clientData
  171. )
  172. /*++
  173. Routine Description:
  174. Add an element to the queue in FIFO fashion.
  175. Arguments:
  176. func - Function associated with new element.
  177. clientData - Client data associated with new element.
  178. Return Value:
  179. TRUE if the new element could be successfully queued. FALSE,
  180. otherwise. If FALSE is returned then GetLastError() can be
  181. used to retrieve the exact error code.
  182. --*/
  183. {
  184. BOOL result;
  185. QUEUEELEMENT element;
  186. DC_BEGIN_FN("W32DispatchQueue::Enqueue");
  187. ASSERT(IsValid());
  188. element.func = func;
  189. element.clientData = clientData;
  190. result = IsValid() && _queue->Enqueue(element);
  191. //
  192. // Signal the data ready event if the enqueue succeeded.
  193. //
  194. if (result) {
  195. SetEvent(_dataReadyEvent);
  196. }
  197. DC_END_FN();
  198. return result;
  199. }
  200. BOOL W32DispatchQueue::Requeue(
  201. IN W32DispatchQueueFunc func,
  202. OPTIONAL IN VOID *clientData,
  203. IN BOOL signalNewData
  204. )
  205. /*++
  206. Routine Description:
  207. Requeue an element at the tail of the queue in LIFO fashion.
  208. Arguments:
  209. func - Function associated with new element.
  210. clientData - Client data associated with new element.
  211. signalNewData - If TRUE then the waitable object associated
  212. with this queue will be signalled.
  213. Return Value:
  214. TRUE if the new element could be successfully queued. FALSE,
  215. otherwise. If FALSE is returned then GetLastError() can be
  216. used to retrieve the exact error code.
  217. --*/
  218. {
  219. DC_BEGIN_FN("W32DispatchQueue::Requeue");
  220. BOOL result;
  221. QUEUEELEMENT element;
  222. ASSERT(IsValid());
  223. element.func = func;
  224. element.clientData = clientData;
  225. result = IsValid() && _queue->Requeue(element);
  226. //
  227. // Signal the data ready event if the enqueue succeeded.
  228. //
  229. if (result && signalNewData) {
  230. SetEvent(_dataReadyEvent);
  231. }
  232. DC_END_FN();
  233. return result;
  234. }