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.

229 lines
4.0 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. tpsutil.cpp
  5. Abstract:
  6. Comtains common utility functions for Win32 thread pool services
  7. Contents:
  8. StartThread
  9. TpsEnter
  10. QueueNullFunc
  11. (NullFunc)
  12. Author:
  13. Richard L Firth (rfirth) 10-Feb-1998
  14. Environment:
  15. Win32 user-mode
  16. Notes:
  17. Taken from NT-specific code written by Gurdeep Singh Pall (gurdeep)
  18. Revision History:
  19. 10-Feb-1998 rfirth
  20. Created
  21. --*/
  22. #include "priv.h"
  23. #include "threads.h"
  24. //
  25. // private prototypes
  26. //
  27. PRIVATE
  28. VOID
  29. NullFunc(
  30. IN LPVOID pUnused
  31. );
  32. //
  33. // functions
  34. //
  35. DWORD
  36. StartThread(
  37. IN LPTHREAD_START_ROUTINE pfnFunction,
  38. OUT PHANDLE phThread,
  39. IN BOOL fSynchronize
  40. )
  41. /*++
  42. Routine Description:
  43. This routine is used start a new thread in the pool. If required, we
  44. synchronize with the new thread using an auto-reset event that the new
  45. thread must signal once it has completed its initialization
  46. Arguments:
  47. pfnFunction - pointer to thread function to start
  48. phThread - pointer to returned thread handle
  49. fSynchronize - used to indicate if we need to synchronize with the new
  50. thread before returning
  51. Return Value:
  52. DWORD
  53. Success - ERROR_SUCCESS
  54. Failure - ERROR_NOT_ENOUGH_MEMORY
  55. Out of memory
  56. --*/
  57. {
  58. HANDLE hSyncEvent = NULL;
  59. if (fSynchronize) {
  60. hSyncEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  61. if (hSyncEvent == NULL) {
  62. return GetLastError();
  63. }
  64. }
  65. DWORD dwThreadId;
  66. HANDLE hThread;
  67. DWORD error = ERROR_SUCCESS;
  68. hThread = CreateThread(NULL, // lpSecurityAttributes
  69. 0, // dwStackSize (0 == same as init thread)
  70. pfnFunction,
  71. (LPVOID)hSyncEvent,
  72. 0, // dwCreationFlags
  73. &dwThreadId // throw away
  74. );
  75. if (hThread == NULL) {
  76. error = GetLastError();
  77. }
  78. if (hSyncEvent != NULL) {
  79. if (hThread != NULL) {
  80. DWORD status = WaitForSingleObject(hSyncEvent, INFINITE);
  81. if (status == WAIT_FAILED) {
  82. error = GetLastError();
  83. } else if (status == WAIT_TIMEOUT) {
  84. error = WAIT_TIMEOUT;
  85. } else if (status != WAIT_OBJECT_0) {
  86. error = ERROR_GEN_FAILURE; // ?
  87. }
  88. if (ERROR_SUCCESS != error)
  89. {
  90. CloseHandle(hThread);
  91. hThread = NULL;
  92. }
  93. }
  94. CloseHandle(hSyncEvent);
  95. }
  96. *phThread = hThread;
  97. return error;
  98. }
  99. DWORD
  100. TpsEnter(
  101. VOID
  102. )
  103. /*++
  104. Routine Description:
  105. synchronize with thread shutting down via SHTerminateThreadPool(). If
  106. terminating because DLL is unloaded, return error else wait until
  107. termination completed
  108. Arguments:
  109. None.
  110. Return Value:
  111. DWORD
  112. Success - ERROR_SUCCESS
  113. Failure - ERROR_SHUTDOWN_IN_PROGRESS
  114. --*/
  115. {
  116. for (; ; ) {
  117. while (g_bTpsTerminating) {
  118. if (g_bDllTerminating) {
  119. return ERROR_SHUTDOWN_IN_PROGRESS; // error code? looks valid -justmann
  120. }
  121. SleepEx(0, TRUE);
  122. }
  123. InterlockedIncrement((LPLONG)&g_ActiveRequests);
  124. if (!g_bTpsTerminating) {
  125. return ERROR_SUCCESS;
  126. }
  127. InterlockedDecrement((LPLONG)&g_ActiveRequests);
  128. }
  129. }
  130. VOID
  131. QueueNullFunc(
  132. IN HANDLE hThread
  133. )
  134. /*++
  135. Routine Description:
  136. Queues NullFunc as an APC to hThread
  137. Arguments:
  138. hThread - thread to queue for
  139. Return Value:
  140. None.
  141. --*/
  142. {
  143. QueueUserAPC((PAPCFUNC)NullFunc, hThread, NULL);
  144. }
  145. PRIVATE
  146. VOID
  147. NullFunc(
  148. IN LPVOID pUnused
  149. )
  150. /*++
  151. Routine Description:
  152. NULL APC function. Used to allow TerminateThreadPool() to wake up dormant
  153. APC threads
  154. Arguments:
  155. pUnused - unused argument pointer
  156. Return Value:
  157. None.
  158. --*/
  159. {
  160. }