libwinpr-pool: make tests pass on Windows

This commit is contained in:
Marc-André Moreau 2013-01-20 22:39:32 -05:00
parent c048dc4cc4
commit ad9769dfe7
4 changed files with 160 additions and 15 deletions

View File

@ -26,7 +26,9 @@
#include <winpr/synch.h>
#include <winpr/thread.h>
#if (!(defined _WIN32 && (_WIN32_WINNT < 0x0600)))
//#if (!(defined _WIN32 && (_WIN32_WINNT < 0x0600)))
#ifndef _WIN32
typedef DWORD TP_VERSION, *PTP_VERSION;
@ -55,6 +57,8 @@ typedef struct _TP_CLEANUP_GROUP TP_CLEANUP_GROUP, *PTP_CLEANUP_GROUP;
typedef VOID (*PTP_CLEANUP_GROUP_CANCEL_CALLBACK)(PVOID ObjectContext, PVOID CleanupContext);
#if 0
typedef struct _TP_CALLBACK_ENVIRON_V3
{
TP_VERSION Version;
@ -83,25 +87,54 @@ typedef struct _TP_CALLBACK_ENVIRON_V3
typedef TP_CALLBACK_ENVIRON_V3 TP_CALLBACK_ENVIRON, *PTP_CALLBACK_ENVIRON;
#else
typedef struct _TP_CALLBACK_ENVIRON_V1
{
TP_VERSION Version;
PTP_POOL Pool;
PTP_CLEANUP_GROUP CleanupGroup;
PTP_CLEANUP_GROUP_CANCEL_CALLBACK CleanupGroupCancelCallback;
PVOID RaceDll;
struct _ACTIVATION_CONTEXT* ActivationContext;
PTP_SIMPLE_CALLBACK FinalizationCallback;
union
{
DWORD Flags;
struct
{
DWORD LongFunction:1;
DWORD Persistent:1;
DWORD Private:30;
} s;
} u;
} TP_CALLBACK_ENVIRON_V1;
#endif
#endif
typedef struct _TP_WORK TP_WORK, *PTP_WORK;
typedef VOID (*PTP_WORK_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK Work);
typedef struct _TP_TIMER TP_TIMER, *PTP_TIMER;
typedef VOID (*PTP_TIMER_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_TIMER Timer);
typedef DWORD TP_WAIT_RESULT;
typedef struct _TP_WAIT TP_WAIT, *PTP_WAIT;
typedef VOID (*PTP_WAIT_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WAIT Wait, TP_WAIT_RESULT WaitResult);
typedef struct _TP_IO TP_IO, *PTP_IO;
typedef TP_CALLBACK_ENVIRON_V1 TP_CALLBACK_ENVIRON, *PTP_CALLBACK_ENVIRON;
#ifndef _WIN32
typedef VOID (*PTP_WORK_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK Work);
typedef VOID (*PTP_TIMER_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_TIMER Timer);
typedef VOID (*PTP_WAIT_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WAIT Wait, TP_WAIT_RESULT WaitResult);
typedef VOID (*PTP_WIN32_IO_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PVOID Overlapped,
ULONG IoResult, ULONG_PTR NumberOfBytesTransferred, PTP_IO Io);
#endif
/* Synch */
WINPR_API PTP_WAIT CreateThreadpoolWait(PTP_WAIT_CALLBACK pfnwa, PVOID pv, PTP_CALLBACK_ENVIRON pcbe);
@ -170,7 +203,7 @@ 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);
#endif
//#endif
WINPR_API void winpr_pool_dummy();

View File

@ -24,29 +24,82 @@
#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_POOL (WINAPI * pCreateThreadpool)(PVOID reserved);
static VOID (WINAPI * pCloseThreadpool)(PTP_POOL ptpp);
static VOID (WINAPI * pSetThreadpoolThreadMaximum)(PTP_POOL ptpp, DWORD cthrdMost);
static BOOL (WINAPI * pSetThreadpoolThreadMinimum)(PTP_POOL ptpp, DWORD cthrdMic);
static void module_init()
{
if (module_initialized)
return;
kernel32_module = LoadLibraryA("kernel32.dll");
if (!kernel32_module)
return;
module_available = TRUE;
pCreateThreadpool = (void*) GetProcAddress(kernel32_module, "CreateThreadpool");
pCloseThreadpool = (void*) GetProcAddress(kernel32_module, "CloseThreadpool");
pSetThreadpoolThreadMaximum = (void*) GetProcAddress(kernel32_module, "SetThreadpoolThreadMaximum");
pSetThreadpoolThreadMinimum = (void*) GetProcAddress(kernel32_module, "SetThreadpoolThreadMinimum");
}
#endif
PTP_POOL CreateThreadpool(PVOID reserved)
{
#ifdef _WIN32
module_init();
if (pCreateThreadpool)
return pCreateThreadpool(reserved);
#endif
return NULL;
}
VOID CloseThreadpool(PTP_POOL ptpp)
{
#ifdef _WIN32
module_init();
if (pCloseThreadpool)
pCloseThreadpool(ptpp);
#endif
}
VOID SetThreadpoolThreadMaximum(PTP_POOL ptpp, DWORD cthrdMost)
{
#ifdef _WIN32
module_init();
if (pSetThreadpoolThreadMaximum)
pSetThreadpoolThreadMaximum(ptpp, cthrdMost);
#endif
}
BOOL SetThreadpoolThreadMinimum(PTP_POOL ptpp, DWORD cthrdMic)
{
#ifdef _WIN32
module_init();
if (pSetThreadpoolThreadMinimum)
pSetThreadpoolThreadMinimum(ptpp, cthrdMic);
#endif
return FALSE;
}
#endif
/* dummy */
void winpr_pool_dummy()
{

View File

@ -11,7 +11,7 @@ int TestPoolWork(int argc, char* argv[])
{
TP_WORK * work;
work = CreateThreadpoolWork(test_WorkCallback, "world", NULL);
work = CreateThreadpoolWork((PTP_WORK_CALLBACK) test_WorkCallback, "world", NULL);
if (!work)
{

View File

@ -24,32 +24,91 @@
#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_WORK (WINAPI * pCreateThreadpoolWork)(PTP_WORK_CALLBACK pfnwk, PVOID pv, PTP_CALLBACK_ENVIRON pcbe);
static VOID (WINAPI * pCloseThreadpoolWork)(PTP_WORK pwk);
static VOID (WINAPI * pSubmitThreadpoolWork)(PTP_WORK pwk);
static BOOL (WINAPI * pTrySubmitThreadpoolCallback)(PTP_SIMPLE_CALLBACK pfns, PVOID pv, PTP_CALLBACK_ENVIRON pcbe);
static VOID (WINAPI * pWaitForThreadpoolWorkCallbacks)(PTP_WORK pwk, BOOL fCancelPendingCallbacks);
static void module_init()
{
if (module_initialized)
return;
kernel32_module = LoadLibraryA("kernel32.dll");
if (!kernel32_module)
return;
module_available = TRUE;
pCreateThreadpoolWork = (void*) GetProcAddress(kernel32_module, "CreateThreadpoolWork");
pCloseThreadpoolWork = (void*) GetProcAddress(kernel32_module, "CloseThreadpoolWork");
pSubmitThreadpoolWork = (void*) GetProcAddress(kernel32_module, "SubmitThreadpoolWork");
pTrySubmitThreadpoolCallback = (void*) GetProcAddress(kernel32_module, "TrySubmitThreadpoolCallback");
pWaitForThreadpoolWorkCallbacks = (void*) GetProcAddress(kernel32_module, "WaitForThreadpoolWorkCallbacks");
}
#endif
PTP_WORK CreateThreadpoolWork(PTP_WORK_CALLBACK pfnwk, PVOID pv, PTP_CALLBACK_ENVIRON pcbe)
{
#ifdef _WIN32
module_init();
if (pCreateThreadpoolWork)
return pCreateThreadpoolWork(pfnwk, pv, pcbe);
#endif
return NULL;
}
VOID CloseThreadpoolWork(PTP_WORK pwk)
{
#ifdef _WIN32
module_init();
if (pCloseThreadpoolWork)
pCloseThreadpoolWork(pwk);
#endif
}
VOID SubmitThreadpoolWork(PTP_WORK pwk)
{
#ifdef _WIN32
module_init();
if (pSubmitThreadpoolWork)
pSubmitThreadpoolWork(pwk);
#endif
}
BOOL TrySubmitThreadpoolCallback(PTP_SIMPLE_CALLBACK pfns, PVOID pv, PTP_CALLBACK_ENVIRON pcbe)
{
#ifdef _WIN32
module_init();
if (pTrySubmitThreadpoolCallback)
return pTrySubmitThreadpoolCallback(pfns, pv, pcbe);
#endif
return FALSE;
}
VOID WaitForThreadpoolWorkCallbacks(PTP_WORK pwk, BOOL fCancelPendingCallbacks)
{
#ifdef _WIN32
module_init();
if (pWaitForThreadpoolWorkCallbacks)
pWaitForThreadpoolWorkCallbacks(pwk, fCancelPendingCallbacks);
#endif
}
#endif