libwinpr-pool: improve Windows implementation

This commit is contained in:
Marc-André Moreau 2013-01-21 23:34:46 -05:00
parent d4d19d6473
commit a98b8a1390
11 changed files with 291 additions and 39 deletions

View File

@ -167,8 +167,8 @@ WINPR_API VOID WaitForThreadpoolIoCallbacks(PTP_IO pio, BOOL fCancelPendingCallb
/* Clean-up Group */
WINPR_API PTP_CLEANUP_GROUP CreateThreadpoolCleanupGroup();
VOID CloseThreadpoolCleanupGroupMembers(PTP_CLEANUP_GROUP ptpcg, BOOL fCancelPendingCallbacks, PVOID pvCleanupContext);
VOID CloseThreadpoolCleanupGroup(PTP_CLEANUP_GROUP ptpcg);
WINPR_API VOID CloseThreadpoolCleanupGroupMembers(PTP_CLEANUP_GROUP ptpcg, BOOL fCancelPendingCallbacks, PVOID pvCleanupContext);
WINPR_API VOID CloseThreadpoolCleanupGroup(PTP_CLEANUP_GROUP ptpcg);
/* Pool */
@ -201,6 +201,8 @@ WINPR_API VOID LeaveCriticalSectionWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci
WINPR_API VOID FreeLibraryWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HMODULE mod);
WINPR_API VOID DisassociateCurrentThreadFromCallback(PTP_CALLBACK_INSTANCE pci);
/* Dummy */
WINPR_API void winpr_pool_dummy();
#endif /* WINPR_POOL_H */

View File

@ -24,7 +24,40 @@
#include <winpr/crt.h>
#include <winpr/pool.h>
#ifdef _WIN32
static BOOL module_initialized = FALSE;
static BOOL module_available = FALSE;
static HMODULE kernel32_module = NULL;
static BOOL (WINAPI * pCallbackMayRunLong)(PTP_CALLBACK_INSTANCE pci);
static void module_init()
{
if (module_initialized)
return;
kernel32_module = LoadLibraryA("kernel32.dll");
module_initialized = TRUE;
if (!kernel32_module)
return;
module_available = TRUE;
pCallbackMayRunLong = (void*) GetProcAddress(kernel32_module, "CallbackMayRunLong");
}
#endif
BOOL CallbackMayRunLong(PTP_CALLBACK_INSTANCE pci)
{
#ifdef _WIN32
module_init();
if (pCallbackMayRunLong)
return pCallbackMayRunLong(pci);
#else
#endif
return FALSE;
}

View File

@ -24,37 +24,107 @@
#include <winpr/crt.h>
#include <winpr/pool.h>
#if (!(defined _WIN32 && (_WIN32_WINNT < 0x0600)))
#ifdef _WIN32
VOID SetEventWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE evt)
static BOOL module_initialized = FALSE;
static BOOL module_available = FALSE;
static HMODULE kernel32_module = NULL;
static VOID (WINAPI * pSetEventWhenCallbackReturns)(PTP_CALLBACK_INSTANCE pci, HANDLE evt);
static VOID (WINAPI * pReleaseSemaphoreWhenCallbackReturns)(PTP_CALLBACK_INSTANCE pci, HANDLE sem, DWORD crel);
static VOID (WINAPI * pReleaseMutexWhenCallbackReturns)(PTP_CALLBACK_INSTANCE pci, HANDLE mut);
static VOID (WINAPI * pLeaveCriticalSectionWhenCallbackReturns)(PTP_CALLBACK_INSTANCE pci, PCRITICAL_SECTION pcs);
static VOID (WINAPI * pFreeLibraryWhenCallbackReturns)(PTP_CALLBACK_INSTANCE pci, HMODULE mod);
static VOID (WINAPI * pDisassociateCurrentThreadFromCallback)(PTP_CALLBACK_INSTANCE pci);
static void module_init()
{
if (module_initialized)
return;
}
kernel32_module = LoadLibraryA("kernel32.dll");
module_initialized = TRUE;
VOID ReleaseSemaphoreWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE sem, DWORD crel)
{
if (!kernel32_module)
return;
}
VOID ReleaseMutexWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE mut)
{
}
VOID LeaveCriticalSectionWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, PCRITICAL_SECTION pcs)
{
}
VOID FreeLibraryWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HMODULE mod)
{
}
VOID DisassociateCurrentThreadFromCallback(PTP_CALLBACK_INSTANCE pci)
{
module_available = TRUE;
pSetEventWhenCallbackReturns = (void*) GetProcAddress(kernel32_module, "SetEventWhenCallbackReturns");
pReleaseSemaphoreWhenCallbackReturns = (void*) GetProcAddress(kernel32_module, "ReleaseSemaphoreWhenCallbackReturns");
pReleaseMutexWhenCallbackReturns = (void*) GetProcAddress(kernel32_module, "ReleaseMutexWhenCallbackReturns");
pLeaveCriticalSectionWhenCallbackReturns = (void*) GetProcAddress(kernel32_module, "LeaveCriticalSectionWhenCallbackReturns");
pFreeLibraryWhenCallbackReturns = (void*) GetProcAddress(kernel32_module, "FreeLibraryWhenCallbackReturns");
pDisassociateCurrentThreadFromCallback = (void*) GetProcAddress(kernel32_module, "DisassociateCurrentThreadFromCallback");
}
#endif
VOID SetEventWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE evt)
{
#ifdef _WIN32
module_init();
if (pSetEventWhenCallbackReturns)
pSetEventWhenCallbackReturns(pci, evt);
#else
#endif
}
VOID ReleaseSemaphoreWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE sem, DWORD crel)
{
#ifdef _WIN32
module_init();
if (pReleaseSemaphoreWhenCallbackReturns)
pReleaseSemaphoreWhenCallbackReturns(pci, sem, crel);
#else
#endif
}
VOID ReleaseMutexWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE mut)
{
#ifdef _WIN32
module_init();
if (pReleaseMutexWhenCallbackReturns)
pReleaseMutexWhenCallbackReturns(pci, mut);
#else
#endif
}
VOID LeaveCriticalSectionWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, PCRITICAL_SECTION pcs)
{
#ifdef _WIN32
module_init();
if (pLeaveCriticalSectionWhenCallbackReturns)
pLeaveCriticalSectionWhenCallbackReturns(pci, pcs);
#else
#endif
}
VOID FreeLibraryWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HMODULE mod)
{
#ifdef _WIN32
module_init();
if (pFreeLibraryWhenCallbackReturns)
pFreeLibraryWhenCallbackReturns(pci, mod);
#else
#endif
}
VOID DisassociateCurrentThreadFromCallback(PTP_CALLBACK_INSTANCE pci)
{
#ifdef _WIN32
module_init();
if (pDisassociateCurrentThreadFromCallback)
pDisassociateCurrentThreadFromCallback(pci);
#else
#endif
}

View File

@ -28,6 +28,41 @@
#ifdef _WIN32
static BOOL module_initialized = FALSE;
static BOOL module_available = FALSE;
static HMODULE kernel32_module = NULL;
static VOID (WINAPI * pInitializeThreadpoolEnvironment)(PTP_CALLBACK_ENVIRON pcbe);
static VOID (WINAPI * pDestroyThreadpoolEnvironment)(PTP_CALLBACK_ENVIRON pcbe);
static VOID (WINAPI * pSetThreadpoolCallbackPool)(PTP_CALLBACK_ENVIRON pcbe, PTP_POOL ptpp);
static VOID (WINAPI * pSetThreadpoolCallbackCleanupGroup)(PTP_CALLBACK_ENVIRON pcbe, PTP_CLEANUP_GROUP ptpcg, PTP_CLEANUP_GROUP_CANCEL_CALLBACK pfng);
static VOID (WINAPI * pSetThreadpoolCallbackRunsLong)(PTP_CALLBACK_ENVIRON pcbe);
static VOID (WINAPI * pSetThreadpoolCallbackLibrary)(PTP_CALLBACK_ENVIRON pcbe, PVOID mod);
static VOID (WINAPI * pSetThreadpoolCallbackPriority)(PTP_CALLBACK_ENVIRON pcbe, TP_CALLBACK_PRIORITY Priority);
static void module_init()
{
if (module_initialized)
return;
kernel32_module = LoadLibraryA("kernel32.dll");
module_initialized = TRUE;
if (!kernel32_module)
return;
module_available = TRUE;
pInitializeThreadpoolEnvironment = (void*) GetProcAddress(kernel32_module, "InitializeThreadpoolEnvironment");
pDestroyThreadpoolEnvironment = (void*) GetProcAddress(kernel32_module, "DestroyThreadpoolEnvironment");
pSetThreadpoolCallbackPool = (void*) GetProcAddress(kernel32_module, "SetThreadpoolCallbackPool");
pSetThreadpoolCallbackCleanupGroup = (void*) GetProcAddress(kernel32_module, "SetThreadpoolCallbackCleanupGroup");
pSetThreadpoolCallbackRunsLong = (void*) GetProcAddress(kernel32_module, "SetThreadpoolCallbackRunsLong");
pSetThreadpoolCallbackRunsLong = (void*) GetProcAddress(kernel32_module, "SetThreadpoolCallbackRunsLong");
pSetThreadpoolCallbackLibrary = (void*) GetProcAddress(kernel32_module, "SetThreadpoolCallbackLibrary");
pSetThreadpoolCallbackPriority = (void*) GetProcAddress(kernel32_module, "SetThreadpoolCallbackPriority");
}
#else
static TP_CALLBACK_ENVIRON DEFAULT_CALLBACK_ENVIRONMENT =
@ -56,6 +91,10 @@ PTP_CALLBACK_ENVIRON GetDefaultThreadpoolEnvironment()
VOID InitializeThreadpoolEnvironment(PTP_CALLBACK_ENVIRON pcbe)
{
#ifdef _WIN32
module_init();
if (pInitializeThreadpoolEnvironment)
pInitializeThreadpoolEnvironment(pcbe);
#else
pcbe->Version = 1;
pcbe->Pool = NULL;
@ -73,6 +112,10 @@ VOID InitializeThreadpoolEnvironment(PTP_CALLBACK_ENVIRON pcbe)
VOID DestroyThreadpoolEnvironment(PTP_CALLBACK_ENVIRON pcbe)
{
#ifdef _WIN32
module_init();
if (pDestroyThreadpoolEnvironment)
pDestroyThreadpoolEnvironment(pcbe);
#else
#endif
}
@ -80,6 +123,10 @@ VOID DestroyThreadpoolEnvironment(PTP_CALLBACK_ENVIRON pcbe)
VOID SetThreadpoolCallbackPool(PTP_CALLBACK_ENVIRON pcbe, PTP_POOL ptpp)
{
#ifdef _WIN32
module_init();
if (pSetThreadpoolCallbackPool)
pSetThreadpoolCallbackPool(pcbe, ptpp);
#else
pcbe->Pool = ptpp;
#endif
@ -88,6 +135,10 @@ VOID SetThreadpoolCallbackPool(PTP_CALLBACK_ENVIRON pcbe, PTP_POOL ptpp)
VOID SetThreadpoolCallbackCleanupGroup(PTP_CALLBACK_ENVIRON pcbe, PTP_CLEANUP_GROUP ptpcg, PTP_CLEANUP_GROUP_CANCEL_CALLBACK pfng)
{
#ifdef _WIN32
module_init();
if (pSetThreadpoolCallbackCleanupGroup)
pSetThreadpoolCallbackCleanupGroup(pcbe, ptpcg, pfng);
#else
pcbe->CleanupGroup = ptpcg;
pcbe->CleanupGroupCancelCallback = pfng;
@ -97,6 +148,10 @@ VOID SetThreadpoolCallbackCleanupGroup(PTP_CALLBACK_ENVIRON pcbe, PTP_CLEANUP_GR
VOID SetThreadpoolCallbackRunsLong(PTP_CALLBACK_ENVIRON pcbe)
{
#ifdef _WIN32
module_init();
if (pSetThreadpoolCallbackRunsLong)
pSetThreadpoolCallbackRunsLong(pcbe);
#else
pcbe->u.s.LongFunction = TRUE;
#endif
@ -105,6 +160,10 @@ VOID SetThreadpoolCallbackRunsLong(PTP_CALLBACK_ENVIRON pcbe)
VOID SetThreadpoolCallbackLibrary(PTP_CALLBACK_ENVIRON pcbe, PVOID mod)
{
#ifdef _WIN32
module_init();
if (pSetThreadpoolCallbackLibrary)
pSetThreadpoolCallbackLibrary(pcbe, mod);
#else
#endif
}
@ -112,6 +171,10 @@ VOID SetThreadpoolCallbackLibrary(PTP_CALLBACK_ENVIRON pcbe, PVOID mod)
VOID SetThreadpoolCallbackPriority(PTP_CALLBACK_ENVIRON pcbe, TP_CALLBACK_PRIORITY Priority)
{
#ifdef _WIN32
module_init();
if (pSetThreadpoolCallbackPriority)
pSetThreadpoolCallbackPriority(pcbe, Priority);
#else
#endif
}

View File

@ -24,22 +24,68 @@
#include <winpr/crt.h>
#include <winpr/pool.h>
#if (!(defined _WIN32 && (_WIN32_WINNT < 0x0600)))
#ifdef _WIN32
static BOOL module_initialized = FALSE;
static BOOL module_available = FALSE;
static HMODULE kernel32_module = NULL;
static PTP_CLEANUP_GROUP (WINAPI * pCreateThreadpoolCleanupGroup)();
static VOID (WINAPI * pCloseThreadpoolCleanupGroupMembers)(PTP_CLEANUP_GROUP ptpcg, BOOL fCancelPendingCallbacks, PVOID pvCleanupContext);
static VOID (WINAPI * pCloseThreadpoolCleanupGroup)(PTP_CLEANUP_GROUP ptpcg);
static void module_init()
{
if (module_initialized)
return;
kernel32_module = LoadLibraryA("kernel32.dll");
module_initialized = TRUE;
if (!kernel32_module)
return;
module_available = TRUE;
pCreateThreadpoolCleanupGroup = (void*) GetProcAddress(kernel32_module, "CreateThreadpoolCleanupGroup");
pCloseThreadpoolCleanupGroupMembers = (void*) GetProcAddress(kernel32_module, "CloseThreadpoolCleanupGroupMembers");
pCloseThreadpoolCleanupGroup = (void*) GetProcAddress(kernel32_module, "CloseThreadpoolCleanupGroup");
}
#endif
PTP_CLEANUP_GROUP CreateThreadpoolCleanupGroup()
{
#ifdef _WIN32
module_init();
if (pCreateThreadpoolCleanupGroup)
return pCreateThreadpoolCleanupGroup();
#else
#endif
return NULL;
}
VOID CloseThreadpoolCleanupGroupMembers(PTP_CLEANUP_GROUP ptpcg, BOOL fCancelPendingCallbacks, PVOID pvCleanupContext)
{
#ifdef _WIN32
module_init();
if (pCloseThreadpoolCleanupGroupMembers)
pCloseThreadpoolCleanupGroupMembers(ptpcg, fCancelPendingCallbacks, pvCleanupContext);
#else
#endif
}
VOID CloseThreadpoolCleanupGroup(PTP_CLEANUP_GROUP ptpcg)
{
#ifdef _WIN32
module_init();
if (pCloseThreadpoolCleanupGroup)
pCloseThreadpoolCleanupGroup(ptpcg);
#else
#endif
}
#endif

View File

@ -24,8 +24,6 @@
#include <winpr/crt.h>
#include <winpr/pool.h>
#if (!(defined _WIN32 && (_WIN32_WINNT < 0x0600)))
PTP_IO CreateThreadpoolIo(HANDLE fl, PTP_WIN32_IO_CALLBACK pfnio, PVOID pv, PTP_CALLBACK_ENVIRON pcbe)
{
return NULL;
@ -51,5 +49,3 @@ VOID WaitForThreadpoolIoCallbacks(PTP_IO pio, BOOL fCancelPendingCallbacks)
}
#endif

View File

@ -43,6 +43,7 @@ static void module_init()
return;
kernel32_module = LoadLibraryA("kernel32.dll");
module_initialized = TRUE;
if (!kernel32_module)
return;

View File

@ -24,8 +24,6 @@
#include <winpr/crt.h>
#include <winpr/pool.h>
#if (!(defined _WIN32 && (_WIN32_WINNT < 0x0600)))
PTP_WAIT CreateThreadpoolWait(PTP_WAIT_CALLBACK pfnwa, PVOID pv, PTP_CALLBACK_ENVIRON pcbe)
{
return NULL;
@ -46,5 +44,4 @@ VOID WaitForThreadpoolWaitCallbacks(PTP_WAIT pwa, BOOL fCancelPendingCallbacks)
}
#endif

View File

@ -12,7 +12,12 @@ void test_WorkCallback(PTP_CALLBACK_INSTANCE instance, void* context, PTP_WORK w
int TestPoolWork(int argc, char* argv[])
{
int index;
TP_WORK * work;
PTP_POOL pool;
PTP_WORK work;
PTP_CLEANUP_GROUP cleanupGroup;
TP_CALLBACK_ENVIRON environment;
printf("Global Thread Pool\n");
work = CreateThreadpoolWork((PTP_WORK_CALLBACK) test_WorkCallback, "world", NULL);
@ -33,5 +38,46 @@ int TestPoolWork(int argc, char* argv[])
WaitForThreadpoolWorkCallbacks(work, FALSE);
CloseThreadpoolWork(work);
printf("Private Thread Pool\n");
pool = CreateThreadpool(NULL);
SetThreadpoolThreadMinimum(pool, 4);
SetThreadpoolThreadMaximum(pool, 8);
InitializeThreadpoolEnvironment(&environment);
SetThreadpoolCallbackPool(&environment, pool);
cleanupGroup = CreateThreadpoolCleanupGroup();
if (!cleanupGroup)
{
printf("CreateThreadpoolCleanupGroup failure\n");
return -1;
}
SetThreadpoolCallbackCleanupGroup(&environment, cleanupGroup, NULL);
work = CreateThreadpoolWork((PTP_WORK_CALLBACK) test_WorkCallback, "world", &environment);
if (!work)
{
printf("CreateThreadpoolWork failure\n");
return -1;
}
for (index = 0; index < 10; index++)
SubmitThreadpoolWork(work);
WaitForThreadpoolWorkCallbacks(work, FALSE);
CloseThreadpoolCleanupGroupMembers(cleanupGroup, TRUE, NULL);
CloseThreadpoolCleanupGroup(cleanupGroup);
DestroyThreadpoolEnvironment(&environment);
CloseThreadpool(pool);
return 0;
}

View File

@ -24,8 +24,6 @@
#include <winpr/crt.h>
#include <winpr/pool.h>
#if (!(defined _WIN32 && (_WIN32_WINNT < 0x0600)))
PTP_TIMER CreateThreadpoolTimer(PTP_TIMER_CALLBACK pfnti, PVOID pv, PTP_CALLBACK_ENVIRON pcbe)
{
return NULL;
@ -51,5 +49,4 @@ VOID WaitForThreadpoolTimerCallbacks(PTP_TIMER pti, BOOL fCancelPendingCallbacks
}
#endif

View File

@ -44,6 +44,7 @@ static void module_init()
return;
kernel32_module = LoadLibraryA("kernel32.dll");
module_initialized = TRUE;
if (!kernel32_module)
return;