245 lines
6.4 KiB
C++
245 lines
6.4 KiB
C++
/*++
|
|
Copyright (c) 1998 Microsoft Corporation
|
|
|
|
Module Name:
|
|
thrdsvcs.cxx
|
|
|
|
Abstract:
|
|
|
|
Contains front-end to thread pool services (Tps) functions
|
|
|
|
Contents:
|
|
(LoadKernelEntryPoints)
|
|
SHRegisterWaitForSingleObject
|
|
SHUnregisterWait
|
|
SHQueueUserWorkItem
|
|
SHCreateTimerQueue
|
|
SHDeleteTimerQueue
|
|
SHSetTimerQueueTimer
|
|
SHChangeTimerQueueTimer
|
|
SHCancelTimerQueueTimer
|
|
|
|
Author:
|
|
Richard L Firth (rfirth) 27-Jan-1998
|
|
|
|
Environment:
|
|
User-mode Win32
|
|
|
|
Notes:
|
|
On NT5 and above, these functions just call the Rtl primitives in NTDLL.DLL.
|
|
On NT4 and Win9x, these functions call the thread pool primitives in
|
|
thread.cxx
|
|
|
|
Revision History:
|
|
|
|
27-Jan-1998 rfirth
|
|
Created
|
|
|
|
--*/
|
|
|
|
#include "priv.h"
|
|
#include "threads.h"
|
|
|
|
|
|
// types
|
|
|
|
|
|
typedef HANDLE (WINAPI * t_RegisterWaitForSingleObject)(HANDLE,
|
|
WAITORTIMERCALLBACKFUNC,
|
|
LPVOID,
|
|
DWORD
|
|
);
|
|
typedef BOOL (WINAPI * t_UnregisterWait)(HANDLE);
|
|
typedef BOOL (WINAPI * t_QueueUserWorkItem)(LPTHREAD_START_ROUTINE, LPVOID, BOOL);
|
|
typedef HANDLE (WINAPI * t_CreateTimerQueue)(VOID);
|
|
typedef BOOL (WINAPI * t_DeleteTimerQueue)(HANDLE);
|
|
typedef HANDLE (WINAPI * t_SetTimerQueueTimer)(HANDLE,
|
|
WAITORTIMERCALLBACKFUNC,
|
|
LPVOID,
|
|
DWORD,
|
|
DWORD,
|
|
BOOL
|
|
);
|
|
typedef BOOL (WINAPI * t_ChangeTimerQueueTimer)(HANDLE, HANDLE, DWORD, DWORD);
|
|
typedef BOOL (WINAPI * t_CancelTimerQueueTimer)(HANDLE, HANDLE);
|
|
|
|
|
|
// global data
|
|
|
|
|
|
t_RegisterWaitForSingleObject _I_RegisterWaitForSingleObject;
|
|
t_UnregisterWait _I_UnregisterWait;
|
|
t_QueueUserWorkItem _I_QueueUserWorkItem;
|
|
t_CreateTimerQueue _I_CreateTimerQueue;
|
|
t_DeleteTimerQueue _I_DeleteTimerQueue;
|
|
t_SetTimerQueueTimer _I_SetTimerQueueTimer;
|
|
t_ChangeTimerQueueTimer _I_ChangeTimerQueueTimer;
|
|
t_CancelTimerQueueTimer _I_CancelTimerQueueTimer;
|
|
|
|
BOOL g_bInitDone = FALSE;
|
|
|
|
|
|
// functions
|
|
|
|
|
|
VOID
|
|
LoadKernelEntryPoints(
|
|
VOID
|
|
)
|
|
{
|
|
static BOOL bLoading = FALSE;
|
|
|
|
if (!InterlockedExchange((LPLONG)&bLoading, TRUE)) {
|
|
|
|
HMODULE hKernel32 = GetModuleHandle("KERNEL32.DLL");
|
|
//BOOL bUseNtEntryPoints = TRUE;
|
|
BOOL bUseNtEntryPoints = FALSE;
|
|
|
|
#define LOAD_ENTRY_POINT(handle, name) \
|
|
if (bUseNtEntryPoints) { \
|
|
_I_##name = (t_##name)GetProcAddress(handle, #name); \
|
|
bUseNtEntryPoints &= (_I_##name != NULL); \
|
|
}
|
|
|
|
if (hKernel32 != NULL) {
|
|
LOAD_ENTRY_POINT(hKernel32, RegisterWaitForSingleObject);
|
|
LOAD_ENTRY_POINT(hKernel32, UnregisterWait);
|
|
LOAD_ENTRY_POINT(hKernel32, QueueUserWorkItem);
|
|
LOAD_ENTRY_POINT(hKernel32, CreateTimerQueue);
|
|
LOAD_ENTRY_POINT(hKernel32, DeleteTimerQueue);
|
|
LOAD_ENTRY_POINT(hKernel32, SetTimerQueueTimer);
|
|
LOAD_ENTRY_POINT(hKernel32, ChangeTimerQueueTimer);
|
|
LOAD_ENTRY_POINT(hKernel32, CancelTimerQueueTimer);
|
|
} else {
|
|
bUseNtEntryPoints = FALSE;
|
|
}
|
|
if (!bUseNtEntryPoints) {
|
|
_I_RegisterWaitForSingleObject = Tps::Ie_RegisterWaitForSingleObject;
|
|
_I_UnregisterWait = Tps::Ie_UnregisterWait;
|
|
_I_QueueUserWorkItem = Tps::Ie_QueueUserWorkItem;
|
|
_I_CreateTimerQueue = Tps::Ie_CreateTimerQueue;
|
|
_I_DeleteTimerQueue = Tps::Ie_DeleteTimerQueue;
|
|
_I_SetTimerQueueTimer = Tps::Ie_SetTimerQueueTimer;
|
|
_I_ChangeTimerQueueTimer = Tps::Ie_ChangeTimerQueueTimer;
|
|
_I_CancelTimerQueueTimer = Tps::Ie_CancelTimerQueueTimer;
|
|
}
|
|
g_bInitDone = TRUE;
|
|
} else {
|
|
while (!g_bInitDone) {
|
|
SleepEx(0, FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
LWSTDAPI_(HANDLE)
|
|
SHRegisterWaitForSingleObject(
|
|
IN HANDLE hObject,
|
|
IN WAITORTIMERCALLBACKFUNC pfnCallback,
|
|
IN LPVOID pContext,
|
|
IN DWORD dwMilliseconds
|
|
)
|
|
{
|
|
if (!g_bInitDone) {
|
|
LoadKernelEntryPoints();
|
|
}
|
|
return _I_RegisterWaitForSingleObject(hObject,
|
|
pfnCallback,
|
|
pContext,
|
|
dwMilliseconds
|
|
);
|
|
}
|
|
|
|
LWSTDAPI_(BOOL)
|
|
SHUnregisterWait(
|
|
IN HANDLE hWait
|
|
)
|
|
{
|
|
if (!g_bInitDone) {
|
|
LoadKernelEntryPoints();
|
|
}
|
|
return _I_UnregisterWait(hWait);
|
|
}
|
|
|
|
LWSTDAPI_(BOOL)
|
|
SHQueueUserWorkItem(
|
|
IN LPTHREAD_START_ROUTINE pfnCallback,
|
|
IN LPVOID pContext,
|
|
IN BOOL bPreferIo
|
|
)
|
|
{
|
|
if (!g_bInitDone) {
|
|
LoadKernelEntryPoints();
|
|
}
|
|
return _I_QueueUserWorkItem(pfnCallback, pContext, bPreferIo);
|
|
}
|
|
|
|
LWSTDAPI_(HANDLE)
|
|
SHCreateTimerQueue(
|
|
VOID
|
|
)
|
|
{
|
|
if (!g_bInitDone) {
|
|
LoadKernelEntryPoints();
|
|
}
|
|
return _I_CreateTimerQueue();
|
|
}
|
|
|
|
LWSTDAPI_(BOOL)
|
|
SHDeleteTimerQueue(
|
|
IN HANDLE hQueue
|
|
)
|
|
{
|
|
if (!g_bInitDone) {
|
|
LoadKernelEntryPoints();
|
|
}
|
|
return _I_DeleteTimerQueue(hQueue);
|
|
}
|
|
|
|
LWSTDAPI_(HANDLE)
|
|
SHSetTimerQueueTimer(
|
|
IN HANDLE hQueue,
|
|
IN WAITORTIMERCALLBACKFUNC pfnCallback,
|
|
IN LPVOID pContext,
|
|
IN DWORD dwDueTime,
|
|
IN DWORD dwPeriod,
|
|
IN BOOL bPreferIo
|
|
)
|
|
{
|
|
if (!g_bInitDone) {
|
|
LoadKernelEntryPoints();
|
|
}
|
|
return _I_SetTimerQueueTimer(hQueue,
|
|
pfnCallback,
|
|
pContext,
|
|
dwDueTime,
|
|
dwPeriod,
|
|
bPreferIo
|
|
);
|
|
}
|
|
|
|
LWSTDAPI_(BOOL)
|
|
SHChangeTimerQueueTimer(
|
|
IN HANDLE hQueue,
|
|
IN HANDLE hTimer,
|
|
IN DWORD dwDueTime,
|
|
IN DWORD dwPeriod
|
|
)
|
|
{
|
|
if (!g_bInitDone) {
|
|
LoadKernelEntryPoints();
|
|
}
|
|
return _I_ChangeTimerQueueTimer(hQueue, hTimer, dwDueTime, dwPeriod);
|
|
}
|
|
|
|
LWSTDAPI_(BOOL)
|
|
SHCancelTimerQueueTimer(
|
|
IN HANDLE hQueue,
|
|
IN HANDLE hTimer
|
|
)
|
|
{
|
|
if (!g_bInitDone) {
|
|
LoadKernelEntryPoints();
|
|
}
|
|
return _I_CancelTimerQueueTimer(hQueue, hTimer);
|
|
}
|