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.

210 lines
5.1 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: DMGQ.C
  3. *
  4. * DDE Manager queue control functions.
  5. *
  6. * Created: 9/1/89 Sanford Staab
  7. * Modified:5/31/90 Rich Gartland, Aldus (Windows 3.0 port)
  8. *
  9. * This is a general queue manager - yes another one!
  10. * Queues are each allocated within their own segment and have a
  11. * QST structure associated with that heap. Each queue item
  12. * is allocated within the heap segment. The offset of the items
  13. * address combined with an instance count is used as the item ID.
  14. * This is both unique and allows for instant location of an item.
  15. * New items are added to the head of the queue which is a doubly linked
  16. * list. The next links point to more recent entries, the prev pointers
  17. * to older entries. The next of the head is the tail. The prev of the
  18. * tail is the head. All pointers are far.
  19. * Queue Data may be of any structure type that begins identical to
  20. * a QUEUEITEM structure. Functions that require an cbItem perameter
  21. * should be given the size of the specialized queue item structure.
  22. *
  23. * Copyright (c) 1988, 1989 Microsoft Corporation
  24. \***************************************************************************/
  25. #include "ddemlp.h"
  26. /***************************** Private Function ****************************\
  27. *
  28. * Creates a Queue for items of cbItem.
  29. * Returns NULL on error.
  30. *
  31. *
  32. * History:
  33. * Created 9/1/89 Sanfords
  34. \***************************************************************************/
  35. PQST CreateQ(cbItem)
  36. WORD cbItem;
  37. {
  38. QST cq;
  39. PQST pQ;
  40. cq.cItems = 0;
  41. cq.instLast = 0;
  42. cq.cbItem = cbItem;
  43. cq.pqiHead = NULL;
  44. if (!(cq.hheap = DmgCreateHeap(sizeof(QST) + cbItem << 3)))
  45. return(NULL);
  46. if (!(pQ = (PQST)FarAllocMem(cq.hheap, sizeof(QST)))) {
  47. DmgDestroyHeap(cq.hheap);
  48. return(0);
  49. }
  50. *pQ = cq;
  51. return(pQ);
  52. }
  53. /***************************** Private Function ****************************\
  54. *
  55. *
  56. * History:
  57. * Created 9/1/89 Sanfords
  58. \***************************************************************************/
  59. BOOL DestroyQ(pQ)
  60. PQST pQ;
  61. {
  62. if (pQ)
  63. DmgDestroyHeap(pQ->hheap);
  64. return(TRUE);
  65. }
  66. /***************************** Private Function ****************************\
  67. *
  68. * returns a long pointer to the queue item data created. The new item
  69. * is added to the head of the queue. The queue's cbItem specified at
  70. * creation is used for allocation.
  71. *
  72. *
  73. * History:
  74. * Created 9/1/89 Sanfords
  75. \***************************************************************************/
  76. PQUEUEITEM Addqi(pQ)
  77. PQST pQ;
  78. {
  79. PQUEUEITEM pqi;
  80. if ((pqi = (PQUEUEITEM)FarAllocMem(pQ->hheap, pQ->cbItem)) == NULL) {
  81. return(NULL);
  82. }
  83. SEMENTER();
  84. if (pQ->cItems == 0) {
  85. pQ->pqiHead = pqi->prev = pqi->next = pqi;
  86. } else {
  87. pqi->prev = pQ->pqiHead;
  88. pqi->next = pQ->pqiHead->next;
  89. pQ->pqiHead->next->prev = pqi;
  90. pQ->pqiHead->next = pqi;
  91. pQ->pqiHead = pqi;
  92. }
  93. SEMLEAVE();
  94. pQ->cItems++;
  95. pqi->inst = ++pQ->instLast;
  96. return(pqi);
  97. }
  98. /***************************** Private Function ****************************\
  99. *
  100. * The id given is an external LONG id, not an item instance number.
  101. * If id is QID_NEWEST, the head item is deleted.
  102. * If id is QID_OLDEST, the tail item is deleted.
  103. *
  104. *
  105. * History:
  106. * Created 9/1/89 Sanfords
  107. \***************************************************************************/
  108. void Deleteqi(pQ, id)
  109. PQST pQ;
  110. DWORD id;
  111. {
  112. PQUEUEITEM pqi;
  113. SEMENTER();
  114. pqi = Findqi(pQ, id);
  115. if (pqi == NULL) {
  116. SEMLEAVE();
  117. return;
  118. }
  119. pqi->prev->next = pqi->next;
  120. pqi->next->prev = pqi->prev;
  121. if (pqi == pQ->pqiHead)
  122. pQ->pqiHead = pqi->prev;
  123. if (!(--pQ->cItems))
  124. pQ->pqiHead = NULL;
  125. FarFreeMem((LPSTR)pqi);
  126. SEMLEAVE();
  127. }
  128. /***************************** Private Function ****************************\
  129. *
  130. * The id given is an external LONG id, not an item instance number.
  131. *
  132. * if id == QID_NEWEST, returns the head queue data item.
  133. * if id == QID_OLDEST == 0L, returns the tail queue data item.
  134. * if the id is not found or the queue is empty, NULL is returned.
  135. * if found, pqi is returned.
  136. *
  137. *
  138. * History:
  139. * Created 9/1/89 Sanfords
  140. \***************************************************************************/
  141. PQUEUEITEM Findqi(pQ, id)
  142. PQST pQ;
  143. DWORD id;
  144. {
  145. PQUEUEITEM pqi;
  146. SEMCHECKIN();
  147. if (pQ == NULL || pQ->pqiHead == NULL)
  148. return(NULL);
  149. if (id == QID_OLDEST)
  150. return(pQ->pqiHead->next);
  151. if (id == QID_NEWEST)
  152. return(pQ->pqiHead);
  153. if (id) {
  154. pqi = PFROMID(pQ, id);
  155. if (pqi->inst == HIWORD(id)) {
  156. return(pqi);
  157. }
  158. return(NULL);
  159. }
  160. }
  161. /*
  162. * useful for traversing queues and deleting particular stuff in them.
  163. */
  164. PQUEUEITEM FindNextQi(
  165. PQST pQ,
  166. PQUEUEITEM pqi,
  167. BOOL fDelete)
  168. {
  169. PQUEUEITEM pqiNext;
  170. if (pqi == NULL) {
  171. return(pQ->cItems ? pQ->pqiHead : NULL);
  172. }
  173. pqiNext = pqi->next;
  174. if (fDelete) {
  175. Deleteqi(pQ, MAKEID(pqi));
  176. }
  177. return(pqiNext != pQ->pqiHead && pQ->cItems ? pqiNext : NULL);
  178. }