tpsutil.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 4k
Category:

Windows Kernel

Development Platform:

Visual C++

  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.         }
  89.         CloseHandle(hSyncEvent);
  90.     }
  91.     *phThread = hThread;
  92.     return error;
  93. }
  94. DWORD
  95. TpsEnter(
  96.     VOID
  97.     )
  98. /*++
  99. Routine Description:
  100.     synchronize with thread shutting down via SHTerminateThreadPool(). If
  101.     terminating because DLL is unloaded, return error else wait until
  102.     termination completed
  103. Arguments:
  104.     None.
  105. Return Value:
  106.     DWORD
  107.         Success - ERROR_SUCCESS
  108.         Failure - ERROR_SHUTDOWN_IN_PROGRESS
  109. --*/
  110. {
  111.     for (; ; ) {
  112.         while (g_bTpsTerminating) {
  113.             if (g_bDllTerminating) {
  114.                 return ERROR_SHUTDOWN_IN_PROGRESS; // BUGBUG - error code?
  115.             }
  116.             SleepEx(0, TRUE);
  117.         }
  118.         InterlockedIncrement((LPLONG)&g_ActiveRequests);
  119.         if (!g_bTpsTerminating) {
  120.             return ERROR_SUCCESS;
  121.         }
  122.         InterlockedDecrement((LPLONG)&g_ActiveRequests);
  123.     }
  124. }
  125. VOID
  126. QueueNullFunc(
  127.     IN HANDLE hThread
  128.     )
  129. /*++
  130. Routine Description:
  131.     Queues NullFunc as an APC to hThread
  132. Arguments:
  133.     hThread - thread to queue for
  134. Return Value:
  135.     None.
  136. --*/
  137. {
  138.     QueueUserAPC((PAPCFUNC)NullFunc, hThread, NULL);
  139. }
  140. PRIVATE
  141. VOID
  142. NullFunc(
  143.     IN LPVOID pUnused
  144.     )
  145. /*++
  146. Routine Description:
  147.     NULL APC function. Used to allow TerminateThreadPool() to wake up dormant
  148.     APC threads
  149. Arguments:
  150.     pUnused - unused argument pointer
  151. Return Value:
  152.     None.
  153. --*/
  154. {
  155. }