From ad9769dfe7bb4d08b73a2cf37603ba6b8ab1aa6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 20 Jan 2013 22:39:32 -0500 Subject: [PATCH] libwinpr-pool: make tests pass on Windows --- winpr/include/winpr/pool.h | 53 +++++++++++++++++---- winpr/libwinpr/pool/pool.c | 57 +++++++++++++++++++++- winpr/libwinpr/pool/test/TestPoolWork.c | 2 +- winpr/libwinpr/pool/work.c | 63 ++++++++++++++++++++++++- 4 files changed, 160 insertions(+), 15 deletions(-) diff --git a/winpr/include/winpr/pool.h b/winpr/include/winpr/pool.h index 4f2416aa0..eda92e773 100644 --- a/winpr/include/winpr/pool.h +++ b/winpr/include/winpr/pool.h @@ -26,7 +26,9 @@ #include #include -#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(); diff --git a/winpr/libwinpr/pool/pool.c b/winpr/libwinpr/pool/pool.c index 941bafe2e..504866dc0 100644 --- a/winpr/libwinpr/pool/pool.c +++ b/winpr/libwinpr/pool/pool.c @@ -24,29 +24,82 @@ #include #include -#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() { diff --git a/winpr/libwinpr/pool/test/TestPoolWork.c b/winpr/libwinpr/pool/test/TestPoolWork.c index 15ef70d6a..1ba2ed8b0 100644 --- a/winpr/libwinpr/pool/test/TestPoolWork.c +++ b/winpr/libwinpr/pool/test/TestPoolWork.c @@ -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) { diff --git a/winpr/libwinpr/pool/work.c b/winpr/libwinpr/pool/work.c index 62db5c7c8..435e2f887 100644 --- a/winpr/libwinpr/pool/work.c +++ b/winpr/libwinpr/pool/work.c @@ -24,32 +24,91 @@ #include #include -#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