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.

332 lines
7.6 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name :
  4. wtblobj.c
  5. Abstract:
  6. Manage a list of waitable objects and associated callbacks.
  7. Author:
  8. TadB
  9. Revision History:
  10. --*/
  11. #include <precomp.h>
  12. #pragma hdrstop
  13. #include "drdbg.h"
  14. #include "errorlog.h"
  15. #include "tsnutl.h"
  16. #include "wtblobj.h"
  17. ////////////////////////////////////////////////////////
  18. //
  19. // Define
  20. //
  21. #define WTBLOBJMGR_MAGICNO 0x57575757
  22. ////////////////////////////////////////////////////////
  23. //
  24. // Local Typedefs
  25. //
  26. typedef struct tagWAITABLEOBJECTMGR
  27. {
  28. #if DBG
  29. DWORD magicNo;
  30. #endif
  31. WTBLOBJ_ClientFunc funcs[MAXIMUM_WAIT_OBJECTS];
  32. HANDLE objects[MAXIMUM_WAIT_OBJECTS];
  33. PVOID clientData[MAXIMUM_WAIT_OBJECTS];
  34. ULONG objectCount;
  35. } WAITABLEOBJECTMGR, *PWAITABLEOBJECTMGR;
  36. ////////////////////////////////////////////////////////
  37. //
  38. // Globals
  39. //
  40. extern DWORD GLOBAL_DEBUG_FLAGS;
  41. WTBLOBJMGR
  42. WTBLOBJ_CreateWaitableObjectMgr()
  43. /*++
  44. Routine Description:
  45. Create a new instance of the Waitable Object Manager.
  46. Arguments:
  47. Return Value:
  48. NULL on error. Otherwise, a new Waitable Object Manager is
  49. returned.
  50. --*/
  51. {
  52. PWAITABLEOBJECTMGR objMgr;
  53. DBGMSG(DBG_TRACE, ("WTBLOBJ_CreateWaitableObjectMgr: Start.\n"));
  54. objMgr = ALLOCMEM(sizeof(WAITABLEOBJECTMGR));
  55. if (objMgr != NULL) {
  56. #if DBG
  57. objMgr->magicNo = WTBLOBJMGR_MAGICNO;
  58. #endif
  59. objMgr->objectCount = 0;
  60. memset(&objMgr->objects[0], 0, sizeof(objMgr->objects));
  61. memset(&objMgr->funcs[0], 0, sizeof(objMgr->funcs));
  62. memset(&objMgr->clientData[0], 0, sizeof(objMgr->clientData));
  63. }
  64. else {
  65. DBGMSG(DBG_ERROR,
  66. ("WTBLOBJ_CreateWaitableObjectMgr: Error in memory allocation.\n")
  67. );
  68. }
  69. DBGMSG(DBG_TRACE, ("WTBLOBJ_CreateWaitableObjectMgr: Finish.\n"));
  70. return objMgr;
  71. }
  72. VOID
  73. WTBLOBJ_DeleteWaitableObjectMgr(
  74. IN WTBLOBJMGR mgr
  75. )
  76. /*++
  77. Routine Description:
  78. Release an instance of the Waitable Object Manager that was
  79. created via a call to WTBLOBJ_CreateWaitableObjectMgr.
  80. Arguments:
  81. mgr - Waitable object manager.
  82. Return Value:
  83. NULL on error. Otherwise, a new Waitable Object Manager is
  84. returned.
  85. --*/
  86. {
  87. PWAITABLEOBJECTMGR objMgr = (PWAITABLEOBJECTMGR)mgr;
  88. DBGMSG(DBG_TRACE, ("WTBLOBJ_DeleteWaitableObjectMgr: Start.\n"));
  89. ASSERT(objMgr->magicNo == WTBLOBJMGR_MAGICNO);
  90. ASSERT(objMgr->objectCount == 0);
  91. #if DBG
  92. objMgr->magicNo = 0xcccccccc;
  93. #endif
  94. FREEMEM(objMgr);
  95. DBGMSG(DBG_TRACE, ("WTBLOBJ_DeleteWaitableObjectMgr: Finish.\n"));
  96. }
  97. DWORD
  98. WTBLOBJ_AddWaitableObject(
  99. IN WTBLOBJMGR mgr,
  100. IN PVOID clientData,
  101. IN HANDLE waitableObject,
  102. IN WTBLOBJ_ClientFunc func
  103. )
  104. /*++
  105. Routine Description:
  106. Add a new waitable object to an existing Waitable Object Manager.
  107. Arguments:
  108. mgr - Waitable object manager.
  109. clientData - Associated client data.
  110. waitableObject - Associated waitable object.
  111. func - Completion callback function.
  112. Return Value:
  113. ERROR_SUCCESS on success. Otherwise, a Windows error code is
  114. returned.
  115. --*/
  116. {
  117. ULONG objectCount;
  118. DWORD retCode = ERROR_SUCCESS;
  119. PWAITABLEOBJECTMGR objMgr = (PWAITABLEOBJECTMGR)mgr;
  120. DBGMSG(DBG_TRACE, ("WTBLOBJ_AddWaitableObject: Start.\n"));
  121. ASSERT(objMgr->magicNo == WTBLOBJMGR_MAGICNO);
  122. objectCount = objMgr->objectCount;
  123. //
  124. // Make sure we don't run out of waitable objects. This version
  125. // only supports MAXIMUM_WAIT_OBJECTS waitable objects.
  126. //
  127. if (objectCount < MAXIMUM_WAIT_OBJECTS) {
  128. ASSERT(objMgr->objects[objectCount] == NULL);
  129. objMgr->funcs[objectCount] = func;
  130. objMgr->objects[objectCount] = waitableObject;
  131. objMgr->clientData[objectCount] = clientData;
  132. objMgr->objectCount++;
  133. }
  134. else {
  135. ASSERT(FALSE);
  136. retCode = ERROR_INSUFFICIENT_BUFFER;
  137. }
  138. DBGMSG(DBG_TRACE, ("WTBLOBJ_AddWaitableObject: Finish.\n"));
  139. return retCode;
  140. }
  141. VOID
  142. WTBLOBJ_RemoveWaitableObject(
  143. IN WTBLOBJMGR mgr,
  144. IN HANDLE waitableObject
  145. )
  146. /*++
  147. Routine Description:
  148. Remove a waitable object via a call to WTBLOBJ_AddWaitableObject.
  149. Arguments:
  150. mgr - Waitable object manager.
  151. waitableObject - Associated waitable object.
  152. Return Value:
  153. NA
  154. --*/
  155. {
  156. ULONG offset;
  157. PWAITABLEOBJECTMGR objMgr = (PWAITABLEOBJECTMGR)mgr;
  158. DBGMSG(DBG_TRACE, ("WTBLOBJ_RemoveWaitableObject: Start.\n"));
  159. ASSERT(objMgr->magicNo == WTBLOBJMGR_MAGICNO);
  160. //
  161. // Find the waitable object in the list, using a linear search.
  162. //
  163. for (offset=0; offset<objMgr->objectCount; offset++) {
  164. if (objMgr->objects[offset] == waitableObject) {
  165. break;
  166. }
  167. }
  168. if (offset < objMgr->objectCount) {
  169. //
  170. // Move the last items to the now vacant spot and decrement the count.
  171. //
  172. objMgr->objects[offset] = objMgr->objects[objMgr->objectCount - 1];
  173. objMgr->funcs[offset] = objMgr->funcs[objMgr->objectCount - 1];
  174. objMgr->clientData[offset] = objMgr->clientData[objMgr->objectCount - 1];
  175. //
  176. // Clear the unused spot.
  177. //
  178. objMgr->objects[objMgr->objectCount - 1] = NULL;
  179. objMgr->funcs[objMgr->objectCount - 1] = NULL;
  180. objMgr->clientData[objMgr->objectCount - 1] = NULL;
  181. objMgr->objectCount--;
  182. }
  183. DBGMSG(DBG_TRACE, ("WTBLOBJ_RemoveWaitableObject: Finish.\n"));
  184. }
  185. DWORD
  186. WTBLOBJ_PollWaitableObjects(
  187. WTBLOBJMGR mgr
  188. )
  189. /*++
  190. Routine Description:
  191. Poll the list of waitable objects associated with a
  192. Waitable Object manager, until the next waitable object
  193. is signaled.
  194. Arguments:
  195. waitableObject - Associated waitable object.
  196. Return Value:
  197. ERROR_SUCCESS on success. Otherwise, a Windows error status
  198. is returned.
  199. --*/
  200. {
  201. DWORD waitResult, objectOffset;
  202. DWORD ret = ERROR_SUCCESS;
  203. HANDLE obj;
  204. WTBLOBJ_ClientFunc func;
  205. PVOID clientData;
  206. PWAITABLEOBJECTMGR objMgr = (PWAITABLEOBJECTMGR)mgr;
  207. DBGMSG(DBG_TRACE, ("WTBLOBJ_PollWaitableObjects: Start.\n"));
  208. ASSERT(objMgr->magicNo == WTBLOBJMGR_MAGICNO);
  209. //
  210. // Wait for all the waitable objects.
  211. //
  212. waitResult = WaitForMultipleObjectsEx(
  213. objMgr->objectCount,
  214. objMgr->objects,
  215. FALSE,
  216. INFINITE,
  217. FALSE
  218. );
  219. if (waitResult != WAIT_FAILED) {
  220. objectOffset = waitResult - WAIT_OBJECT_0;
  221. ASSERT(objectOffset < objMgr->objectCount);
  222. //
  223. // Call the associated callback.
  224. //
  225. clientData = objMgr->clientData[objectOffset];
  226. func = objMgr->funcs[objectOffset];
  227. obj = objMgr->objects[objectOffset];
  228. func(obj, clientData);
  229. }
  230. else {
  231. ret = GetLastError();
  232. DBGMSG(DBG_ERROR,
  233. ("WTBLOBJ_PollWaitableObjects: WaitForMult failed: %ld\n",
  234. ret));
  235. }
  236. DBGMSG(DBG_TRACE, ("WTBLOBJ_PollWaitableObjects: Finish.\n"));
  237. return ret;
  238. }