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.

230 lines
4.2 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. ASSERT( 0 != g_ActiveRequests );
  128. InterlockedDecrement((LPLONG)&g_ActiveRequests);
  129. }
  130. }
  131. VOID
  132. QueueNullFunc(
  133. IN HANDLE hThread
  134. )
  135. /*++
  136. Routine Description:
  137. Queues NullFunc as an APC to hThread
  138. Arguments:
  139. hThread - thread to queue for
  140. Return Value:
  141. None.
  142. --*/
  143. {
  144. QueueUserAPC((PAPCFUNC)NullFunc, hThread, NULL);
  145. }
  146. PRIVATE
  147. VOID
  148. NullFunc(
  149. IN LPVOID pUnused
  150. )
  151. /*++
  152. Routine Description:
  153. NULL APC function. Used to allow TerminateThreadPool() to wake up dormant
  154. APC threads
  155. Arguments:
  156. pUnused - unused argument pointer
  157. Return Value:
  158. None.
  159. --*/
  160. {
  161. }