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.

362 lines
7.5 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. common\rtutils\wt.h.c
  5. Abstract:
  6. Worker threads for the router process
  7. Revision History:
  8. K.S.Lokesh
  9. created
  10. --*/
  11. #ifndef _WT_H_
  12. #define _WT_H_
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <windows.h>
  17. #include <rtutils.h>
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include "wttrace.h"
  21. #include "log.h"
  22. #define WT_STATUS_CREATED 0
  23. #define WT_STATUS_REGISTERED 1
  24. #define WT_STATUS_INACTIVE 3
  25. #define WT_STATUS_ACTIVE 0x4
  26. #define WT_STATUS_FIRED 0x8
  27. #define WT_STATUS_DELETED 0xFFFFFFFF
  28. //
  29. // WAIT_THREAD_ENTRY structure maintained by each wait-thread
  30. //
  31. typedef struct _WAIT_THREAD_ENTRY {
  32. DWORD wte_ServerId; // id of the wait thread
  33. DWORD wte_ThreadId; // thread id of the wait thread server
  34. DWORD wte_NumClients;
  35. // list for timers/events
  36. LIST_ENTRY wteL_ClientEventEntries; // list of current client events
  37. LIST_ENTRY wteL_ClientTimerEntries; // list of current client timers
  38. HANDLE wte_Timer;
  39. LONGLONG wte_Timeout; // time when the timer is set to go off
  40. CRITICAL_SECTION wte_CSTimer;
  41. // array for WaitForMultipleObjects
  42. #define EVENTS_ARRAY_SZ 2*MAXIMUM_WAIT_OBJECTS
  43. PWT_EVENT_ENTRY wteA_EventMapper[EVENTS_ARRAY_SZ]; // maps to list entries
  44. HANDLE wteA_Events[EVENTS_ARRAY_SZ]; // for WaitForMultipleObjects()
  45. DWORD wte_LowIndex;
  46. DWORD wte_NumTotalEvents;
  47. DWORD wte_NumActiveEvents;
  48. DWORD wte_NumHighPriorityEvents;
  49. DWORD wte_NumActiveHighPriorityEvents;
  50. // adding/deleting events/timers
  51. HANDLE wte_ClientNotifyWTEvent; // client->: there are events to be added
  52. HANDLE wte_WTNotifyClientEvent; // WT->client: the events have been added
  53. DWORD wte_ChangeType;
  54. PLIST_ENTRY wtePL_EventsToChange;
  55. PLIST_ENTRY wtePL_TimersToChange;
  56. PWT_WORK_ITEM wteP_BindingToChange;
  57. // add events and then bindings. delete bindings and then events
  58. #define CHANGE_TYPE_NONE 0
  59. #define CHANGE_TYPE_ADD 1
  60. #define CHANGE_TYPE_DELETE 3
  61. #define CHANGE_TYPE_BIND_FUNCTION_ADD 4
  62. #define CHANGE_TYPE_BIND_FUNCTION_DELETE 5
  63. DWORD wte_Status;
  64. DWORD wte_RefCount;
  65. LIST_ENTRY wte_Links;
  66. CRITICAL_SECTION wte_CS;
  67. } WAIT_THREAD_ENTRY, *PWAIT_THREAD_ENTRY;
  68. #define NUM_CLIENT_EVENTS_FREE(pwte) \
  69. (MAXIMUM_WAIT_OBJECTS - pwte->wte_NumTotalEvents)
  70. #define EA_OVERFLOW(pwte, numEventsToAdd) \
  71. (((DWORD)pwte->wte_LowIndex + pwte->wte_NumActiveEvents + numEventsToAdd) \
  72. > (EVENTS_ARRAY_SZ-1))
  73. #define EA_EXISTS_LOW_PRIORITY_EVENT(pwte) \
  74. ((pwte->wte_NumActiveEvents - pwte->wte_NumActiveHighPriorityEvents) > 0)
  75. #define EA_INDEX_LOW_LOW_PRIORITY_EVENT(pwte) \
  76. (pwte->wte_LowIndex + pwte->wte_NumActiveHighPriorityEvents)
  77. #define EA_INDEX_HIGH_LOW_PRIORITY_EVENT(pwte) \
  78. (pwte->wte_LowIndex + pwte->wte_NumActiveEvents -1)
  79. #define EA_INDEX_LOW_HIGH_PRIORITY_EVENT(pwte) \
  80. (pwte->wte_LowIndex)
  81. #define EA_INDEX_HIGH_HIGH_PRIORITY_EVENT(pwte) \
  82. (pwte->wte_LowIndex + pwte->wte_NumActiveHighPriorityEvents - 1)
  83. //
  84. // WAIT_THREAD_GLOBAL structure
  85. //
  86. typedef struct _WAIT_THREAD_GLOBAL {
  87. DWORD g_Initialized;
  88. LIST_ENTRY gL_WaitThreadEntries;
  89. HANDLE g_Heap;
  90. //HANDLE g_InitializedEvent; // set after 1st alertable thread is initialized
  91. CRITICAL_SECTION g_CS;
  92. DWORD g_TraceId;
  93. DWORD g_LogLevel;
  94. HANDLE g_LogHandle;
  95. } WAIT_THREAD_GLOBAL, *PWAIT_THREAD_GLOBAL ;
  96. //
  97. // EXTERN GLOBAL VARIABLES
  98. //
  99. extern WAIT_THREAD_GLOBAL WTG;
  100. //
  101. // PROTOTYPE DECLARATIONS
  102. //
  103. // Create the events and the timer for a server
  104. // called by server only
  105. DWORD
  106. CreateServerEventsAndTimer (
  107. IN PWAIT_THREAD_ENTRY pwte
  108. );
  109. // creates a wait thread entry and initializes it
  110. DWORD
  111. CreateWaitThreadEntry (
  112. IN DWORD dwThreadId,
  113. OUT PWAIT_THREAD_ENTRY *ppwte
  114. );
  115. // deinitializes the global structure for wait-thread
  116. DWORD
  117. DeInitializeWaitGlobal(
  118. );
  119. DWORD
  120. DeleteClientEvent (
  121. IN PWT_EVENT_ENTRY pee,
  122. IN PWAIT_THREAD_ENTRY pwte
  123. );
  124. // removes a wait server thread from the list of servers
  125. DWORD
  126. DeleteWaitThreadEntry (
  127. IN PWAIT_THREAD_ENTRY pwte
  128. );
  129. DWORD
  130. DeRegisterClientEventBinding (
  131. IN PWAIT_THREAD_ENTRY pwte
  132. );
  133. DWORD
  134. DeRegisterClientEventsTimers (
  135. IN PWAIT_THREAD_ENTRY pte
  136. );
  137. VOID
  138. FreeWaitEventBinding (
  139. IN PWT_WORK_ITEM pwiWorkItem
  140. );
  141. DWORD
  142. FreeWaitThreadEntry (
  143. IN PWAIT_THREAD_ENTRY pwte
  144. );
  145. // returns a wait thread which has the required number of free events
  146. PWAIT_THREAD_ENTRY
  147. GetWaitThread (
  148. IN DWORD dwNumEventsToAdd,
  149. IN DWORD dwNumTimersToAdd
  150. );
  151. // initialize the global data structure for all wait threads
  152. DWORD
  153. InitializeWaitGlobal(
  154. );
  155. // Insert the event in the events array and the map array
  156. VOID
  157. InsertInEventsArray (
  158. PWT_EVENT_ENTRY pee,
  159. PWAIT_THREAD_ENTRY pwte
  160. );
  161. // insert an event entry in the events list and increment counters
  162. VOID
  163. InsertInEventsList (
  164. PWT_EVENT_ENTRY pee,
  165. PWAIT_THREAD_ENTRY pwte
  166. );
  167. // insert the new wait server thread into a list of increasing ServerIds
  168. DWORD
  169. InsertWaitThreadEntry (
  170. IN PWAIT_THREAD_ENTRY pwteInsert
  171. );
  172. DWORD
  173. RegisterClientEventLocal (
  174. IN PWT_EVENT_ENTRY pee,
  175. IN PWAIT_THREAD_ENTRY pwte
  176. );
  177. DWORD
  178. RegisterClientEventBinding (
  179. IN PWAIT_THREAD_ENTRY pwte
  180. );
  181. // Process event: waitable timer fired
  182. VOID
  183. WorkerFunction_WaitableTimer(
  184. PVOID pContext
  185. );
  186. VOID
  187. WorkerFunction_ProcessClientNotifyWTEvent (
  188. IN PVOID pContext
  189. );
  190. VOID
  191. WorkerFunction_ProcessWorkQueueTimer (
  192. IN PVOID pContext
  193. );
  194. VOID
  195. WorkerFunction_ProcessAlertableThreadSemaphore (
  196. IN PVOID pContext
  197. );
  198. //
  199. // APIS
  200. //
  201. //
  202. // The client has the lock on the server
  203. DWORD
  204. AddClientEvent (
  205. IN PWT_EVENT_ENTRY pee,
  206. IN PWAIT_THREAD_ENTRY pwte
  207. );
  208. // The client has the lock on the server
  209. DWORD
  210. AddClientTimer (
  211. PWT_TIMER_ENTRY pte,
  212. PWAIT_THREAD_ENTRY pwte
  213. );
  214. DWORD
  215. APIENTRY
  216. AlertableWaitWorkerThread (
  217. LPVOID param
  218. );
  219. DWORD
  220. DeleteClientTimer (
  221. PWT_TIMER_ENTRY pte,
  222. PWAIT_THREAD_ENTRY pwte
  223. );
  224. VOID
  225. FreeWaitEvent (
  226. IN PWT_EVENT_ENTRY peeEvent
  227. );
  228. VOID
  229. FreeWaitTimer (
  230. IN PWT_TIMER_ENTRY pte
  231. );
  232. DWORD
  233. RegisterClientEventsTimers (
  234. PWAIT_THREAD_ENTRY pwte
  235. );
  236. //
  237. // #defines
  238. //
  239. #define WT_MALLOC(sz) HeapAlloc(WTG.g_Heap,0,(sz))
  240. #define WT_FREE(p) HeapFree(WTG.g_Heap, 0, (p))
  241. #define WT_FREE_NOT_NULL(p) ((p) ? WT_FREE(p) : TRUE)
  242. //
  243. // MACROS
  244. //
  245. #define ENTER_WAIT_API() \
  246. ((ENTER_WORKER_API) && (WTG.g_Initialized==0x12345678))
  247. #define SET_TIMER_INFINITE(time) \
  248. time = 0
  249. #define IS_TIMER_INFINITE(time) \
  250. (time == 0)
  251. #endif // _WT_H_