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.
|
|
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
tpsutil.cpp
Abstract:
Comtains common utility functions for Win32 thread pool services
Contents: StartThread TpsEnter QueueNullFunc (NullFunc)
Author:
Richard L Firth (rfirth) 10-Feb-1998
Environment:
Win32 user-mode
Notes:
Taken from NT-specific code written by Gurdeep Singh Pall (gurdeep)
Revision History:
10-Feb-1998 rfirth Created
--*/
#include "priv.h"
#include "threads.h"
//
// private prototypes
//
PRIVATE VOID NullFunc( IN LPVOID pUnused );
//
// functions
//
DWORD StartThread( IN LPTHREAD_START_ROUTINE pfnFunction, OUT PHANDLE phThread, IN BOOL fSynchronize )
/*++
Routine Description:
This routine is used start a new thread in the pool. If required, we synchronize with the new thread using an auto-reset event that the new thread must signal once it has completed its initialization
Arguments:
pfnFunction - pointer to thread function to start
phThread - pointer to returned thread handle
fSynchronize - used to indicate if we need to synchronize with the new thread before returning
Return Value:
DWORD Success - ERROR_SUCCESS
Failure - ERROR_NOT_ENOUGH_MEMORY Out of memory
--*/
{ HANDLE hSyncEvent = NULL;
if (fSynchronize) { hSyncEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (hSyncEvent == NULL) { return GetLastError(); } }
DWORD dwThreadId; HANDLE hThread; DWORD error = ERROR_SUCCESS;
hThread = CreateThread(NULL, // lpSecurityAttributes
0, // dwStackSize (0 == same as init thread)
pfnFunction, (LPVOID)hSyncEvent, 0, // dwCreationFlags
&dwThreadId // throw away
); if (hThread == NULL) { error = GetLastError(); } if (hSyncEvent != NULL) { if (hThread != NULL) {
DWORD status = WaitForSingleObject(hSyncEvent, INFINITE);
if (status == WAIT_FAILED) { error = GetLastError(); } else if (status == WAIT_TIMEOUT) { error = WAIT_TIMEOUT; } else if (status != WAIT_OBJECT_0) { error = ERROR_GEN_FAILURE; // ?
}
if (ERROR_SUCCESS != error) { CloseHandle(hThread); hThread = NULL; } } CloseHandle(hSyncEvent); } *phThread = hThread; return error; }
DWORD TpsEnter( VOID )
/*++
Routine Description:
synchronize with thread shutting down via SHTerminateThreadPool(). If terminating because DLL is unloaded, return error else wait until termination completed
Arguments:
None.
Return Value:
DWORD Success - ERROR_SUCCESS
Failure - ERROR_SHUTDOWN_IN_PROGRESS
--*/
{ for (; ; ) { while (g_bTpsTerminating) { if (g_bDllTerminating) { return ERROR_SHUTDOWN_IN_PROGRESS; // error code? looks valid -justmann
} SleepEx(0, TRUE); } InterlockedIncrement((LPLONG)&g_ActiveRequests); if (!g_bTpsTerminating) { return ERROR_SUCCESS; } InterlockedDecrement((LPLONG)&g_ActiveRequests); } }
VOID QueueNullFunc( IN HANDLE hThread )
/*++
Routine Description:
Queues NullFunc as an APC to hThread
Arguments:
hThread - thread to queue for
Return Value:
None.
--*/
{ QueueUserAPC((PAPCFUNC)NullFunc, hThread, NULL); }
PRIVATE VOID NullFunc( IN LPVOID pUnused )
/*++
Routine Description:
NULL APC function. Used to allow TerminateThreadPool() to wake up dormant APC threads
Arguments:
pUnused - unused argument pointer
Return Value:
None.
--*/
{ }
|