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.

426 lines
9.8 KiB

  1. /***************************************************************************
  2. *
  3. * File: queue.c
  4. *
  5. * INTEL Corporation Proprietary Information
  6. * Copyright (c) 1996 Intel Corporation.
  7. *
  8. * This listing is supplied under the terms of a license agreement
  9. * with INTEL Corporation and may not be used, copied, nor disclosed
  10. * except in accordance with the terms of that agreement.
  11. *
  12. ***************************************************************************
  13. *
  14. * $Workfile: queue.c $
  15. * $Revision: 1.8 $
  16. * $Modtime: 13 Dec 1996 11:48:16 $
  17. * $Log: S:\sturgeon\src\h245ws\vcs\queue.c_v $
  18. *
  19. * Rev 1.8 13 Dec 1996 12:13:12 SBELL1
  20. * moved ifdef _cplusplus to after includes
  21. *
  22. * Rev 1.7 May 28 1996 10:39:00 plantz
  23. * Change QFree to not free objects on the queue; instead it insists that
  24. * the queue be empty.
  25. *
  26. * Rev 1.6 21 May 1996 16:21:36 EHOWARDX
  27. * Added DeleteCriticalSection to QFree().
  28. *
  29. * Rev 1.5 Apr 24 1996 16:18:58 plantz
  30. * Removed include winsock2.h and incommon.h
  31. *
  32. * Rev 1.3.1.0 Apr 24 1996 16:16:42 plantz
  33. * Removed include winsock2.h and callcont.h
  34. *
  35. * Rev 1.3 01 Apr 1996 14:53:28 EHOWARDX
  36. * Changed pQUEUE to PQUEUE.
  37. *
  38. * Rev 1.1 09 Mar 1996 21:12:34 EHOWARDX
  39. * Fixes as result of testing.
  40. *
  41. * Rev 1.0 08 Mar 1996 20:22:38 unknown
  42. * Initial revision.
  43. *
  44. ***************************************************************************/
  45. #ifndef STRICT
  46. #define STRICT
  47. #endif // not defined STRICT
  48. #pragma warning ( disable : 4115 4201 4214 4514 )
  49. #include <nt.h>
  50. #include <ntrtl.h>
  51. #include <nturtl.h>
  52. #include <windows.h>
  53. #include "queue.h"
  54. #include "linkapi.h"
  55. #include "h245ws.h"
  56. #include "provider.h"
  57. #if defined(__cplusplus)
  58. extern "C"
  59. {
  60. #endif // (__cplusplus)
  61. /*-*-------------------------------------------------------------------------
  62. Function Name:
  63. QCreate
  64. Syntax:
  65. PQUEUE QCreate(void);
  66. Parameters:
  67. None.
  68. Summary:
  69. Allocates and initializes a new queue.
  70. Returns:
  71. NULL - Allocation of memory for new queue failed.
  72. Otherwise - Address of new queue created.
  73. -------------------------------------------------------------------------*-*/
  74. PQUEUE QCreate(void)
  75. {
  76. register PQUEUE pQueue; /* pointer to the new queue */
  77. /* Allocate a new queue */
  78. pQueue = (PQUEUE)HWSMALLOC(sizeof(QUEUE));
  79. if (pQueue != NULL)
  80. {
  81. /* Initialize the new queue */
  82. pQueue->nHead = pQueue->nTail = Q_NULL;
  83. __try {
  84. // initialize lock (and allocate event immediately)
  85. InitializeCriticalSectionAndSpinCount(&pQueue->CriticalSection,H323_SPIN_COUNT);
  86. } __except ((GetExceptionCode() == STATUS_NO_MEMORY)
  87. ? EXCEPTION_EXECUTE_HANDLER
  88. : EXCEPTION_CONTINUE_SEARCH
  89. ) {
  90. // free queue
  91. HWSFREE(pQueue);
  92. // re-initialize
  93. pQueue = NULL;
  94. }
  95. }
  96. return pQueue;
  97. } /* QCreate */
  98. void QLock(PQUEUE pQueue)
  99. {
  100. EnterCriticalSection(&pQueue->CriticalSection);
  101. }
  102. void QUnlock(PQUEUE pQueue)
  103. {
  104. LeaveCriticalSection(&pQueue->CriticalSection);
  105. }
  106. LPVOID QFirstItem(PQUEUE pQueue)
  107. {
  108. HWSASSERT(pQueue != NULL);
  109. if (pQueue->nHead == Q_NULL)
  110. {
  111. /* If the queue is empty, we will return NULL */
  112. return NULL;
  113. }
  114. pQueue->nCursor = pQueue->nHead;
  115. return pQueue->apObjects[pQueue->nHead];
  116. }
  117. LPVOID QNextItem(PQUEUE pQueue)
  118. {
  119. pQueue->nCursor = (pQueue->nCursor + 1) % MAX_QUEUE_SIZE;
  120. if (pQueue->nCursor == ((pQueue->nTail + 1) % MAX_QUEUE_SIZE))
  121. {
  122. return NULL;
  123. }
  124. return pQueue->apObjects[pQueue->nCursor];
  125. } /* QNextItem */
  126. LPVOID QRemoveCurrentItem(PQUEUE pQueue)
  127. {
  128. register LPVOID pElem; /* pointer to the new queue */
  129. HWSASSERT(pQueue->nHead != Q_NULL);
  130. pElem = pQueue->apObjects[pQueue->nCursor];
  131. // copy the head element to the current slot and remove the first element.
  132. pQueue->apObjects[pQueue->nCursor] = pQueue->apObjects[pQueue->nHead];
  133. pQueue->apObjects[pQueue->nHead] = NULL;
  134. /* Check to see if we've just emptied the queue; if so, set */
  135. /* the nHead and nTail indices to Q_NULL. If not, set the nHead */
  136. /* index to the right value. */
  137. if (pQueue->nHead == pQueue->nTail)
  138. {
  139. pQueue->nHead = pQueue->nTail = Q_NULL;
  140. }
  141. else
  142. {
  143. pQueue->nHead = (pQueue->nHead + 1) % MAX_QUEUE_SIZE;
  144. }
  145. return pElem;
  146. } /* QRemoveCurrentItem */
  147. /*-*-------------------------------------------------------------------------
  148. Function Name:
  149. QFree
  150. Syntax:
  151. void QFree(PQUEUE pQueue);
  152. Parameters:
  153. pQueue -pointer to the queue to free
  154. Summary:
  155. Deallocates a queue that was allocated by QCreate.
  156. -------------------------------------------------------------------------*-*/
  157. void QFree(PQUEUE pQueue)
  158. {
  159. /* The queue must be empty before it is freed. */
  160. HWSASSERT(pQueue->nHead == Q_NULL);
  161. /* Free the queue. */
  162. DeleteCriticalSection(&pQueue->CriticalSection);
  163. HWSFREE(pQueue);
  164. } /* QFree */
  165. /*
  166. * NAME
  167. * QRemove - remove object from head of queue
  168. *
  169. * ARGUMENTS
  170. * pQueue Pointer to queue
  171. *
  172. * RETURN VALUE
  173. * Pointer to object dequeued or NULL of queue empty
  174. */
  175. /*-*-------------------------------------------------------------------------
  176. Function Name:
  177. QRemove
  178. Syntax:
  179. LPVOID QRemove(PQUEUE pQueue);
  180. Parameters:
  181. pQueue - Pointer to queue.
  182. Summary:
  183. Removes and returns object from head of queue.
  184. Returns:
  185. NULL - Queue was empty.
  186. Otherwise - Address of object dequeued.
  187. -------------------------------------------------------------------------*-*/
  188. LPVOID QRemove(PQUEUE pQueue)
  189. {
  190. register LPVOID pObject; /* pointer to the object to remove */
  191. EnterCriticalSection(&pQueue->CriticalSection);
  192. if (pQueue->nHead == Q_NULL)
  193. {
  194. /* If the queue is empty, we will return NULL */
  195. pObject = NULL;
  196. }
  197. else
  198. {
  199. /* Get the pointer, NULL it in the apObjects array. */
  200. pObject = pQueue->apObjects[pQueue->nHead];
  201. pQueue->apObjects[pQueue->nHead] = NULL;
  202. /* Check to see if we've just emptied the queue; if so, set */
  203. /* the nHead and nTail indices to Q_NULL. If not, set the nHead */
  204. /* index to the right value. */
  205. if (pQueue->nHead == pQueue->nTail)
  206. {
  207. pQueue->nHead = pQueue->nTail = Q_NULL;
  208. }
  209. else
  210. {
  211. pQueue->nHead = (pQueue->nHead + 1) % MAX_QUEUE_SIZE;
  212. }
  213. }
  214. LeaveCriticalSection(&pQueue->CriticalSection);
  215. return pObject;
  216. } /* QRemove */
  217. /*-*-------------------------------------------------------------------------
  218. Function Name:
  219. QInsert
  220. Syntax:
  221. BOOL QInsert(PQUEUE pQueue, LPVOID pObject);
  222. Parameters:
  223. pQueue - Pointer to queue to insert object into.
  224. pObject - Pointer to object to insert into queue.
  225. Summary:
  226. Inserts an object at tail of queue.
  227. Returns:
  228. TRUE - Object successfully added to queue.
  229. FALSE - Queue full; object could not be added.
  230. -------------------------------------------------------------------------*-*/
  231. BOOL QInsert(PQUEUE pQueue, LPVOID pObject)
  232. {
  233. register int iTemp;
  234. EnterCriticalSection(&pQueue->CriticalSection);
  235. /* If the queue is full, set the return value to FALSE and do */
  236. /* nothing; if not, update the indices appropriately and set the */
  237. /* return value to TRUE. */
  238. if (pQueue->nHead == Q_NULL)
  239. {
  240. /* Queue is empty */
  241. pQueue->apObjects[0] = pObject;
  242. pQueue->nHead = pQueue->nTail = 0;
  243. iTemp = TRUE;
  244. }
  245. else
  246. {
  247. iTemp = (pQueue->nTail + 1) % MAX_QUEUE_SIZE;
  248. if (iTemp == pQueue->nHead)
  249. {
  250. /* Queue is full */
  251. iTemp = FALSE;
  252. }
  253. else
  254. {
  255. pQueue->apObjects[iTemp] = pObject;
  256. pQueue->nTail = iTemp;
  257. iTemp = TRUE;
  258. }
  259. }
  260. LeaveCriticalSection(&pQueue->CriticalSection);
  261. return (BOOL) iTemp;
  262. }
  263. /*-*-------------------------------------------------------------------------
  264. Function Name:
  265. QInsertAtHead
  266. Syntax:
  267. BOOL QInsertAtHead(PQUEUE pQueue, LPVOID pObject);
  268. Parameters:
  269. pQueue - Pointer to queue to insert object into.
  270. pObject - Pointer to object to insert into queue.
  271. Summary:
  272. Inserts an object at head of queue.
  273. Returns:
  274. TRUE - Object successfully added to queue.
  275. FALSE - Queue full; object could not be added.
  276. -------------------------------------------------------------------------*-*/
  277. BOOL QInsertAtHead(PQUEUE pQueue, LPVOID pObject)
  278. {
  279. register int iTemp;
  280. EnterCriticalSection(&pQueue->CriticalSection);
  281. if (pQueue->nHead == Q_NULL)
  282. {
  283. /* Queue is empty */
  284. pQueue->apObjects[0] = pObject;
  285. pQueue->nHead = pQueue->nTail = 0;
  286. iTemp = TRUE;
  287. }
  288. else
  289. {
  290. iTemp = (pQueue->nHead + (MAX_QUEUE_SIZE - 1)) % MAX_QUEUE_SIZE;
  291. if (iTemp == pQueue->nTail)
  292. {
  293. /* Queue is full */
  294. iTemp = FALSE;
  295. }
  296. else
  297. {
  298. pQueue->apObjects[iTemp] = pObject;
  299. pQueue->nHead = iTemp;
  300. iTemp = TRUE;
  301. }
  302. }
  303. LeaveCriticalSection(&pQueue->CriticalSection);
  304. return (BOOL) iTemp;
  305. } /* QInsertAtHead */
  306. /*-*-------------------------------------------------------------------------
  307. Function Name:
  308. IsQEmpty
  309. Syntax:
  310. BOOL IsQEmpty(PQUEUE pQueue);
  311. Parameters:
  312. pQueue - Pointer to queue to check.
  313. Summary:
  314. Checks if a queue is empty.
  315. Returns:
  316. TRUE - Queue is empty.
  317. FALSE - Queue contains at least one object.
  318. -------------------------------------------------------------------------*-*/
  319. BOOL IsQEmpty(PQUEUE pQueue)
  320. {
  321. return (pQueue->nHead == Q_NULL ? TRUE : FALSE);
  322. } /* IsQEmpty */
  323. #if defined(__cplusplus)
  324. }
  325. #endif // (__cplusplus)