diff --git a/winpr/include/winpr/pool.h b/winpr/include/winpr/pool.h index 8dc335084..c22804310 100644 --- a/winpr/include/winpr/pool.h +++ b/winpr/include/winpr/pool.h @@ -36,15 +36,6 @@ typedef VOID (*PTP_SIMPLE_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Contex typedef struct _TP_POOL TP_POOL, *PTP_POOL; -typedef enum _TP_CALLBACK_PRIORITY -{ - TP_CALLBACK_PRIORITY_HIGH, - TP_CALLBACK_PRIORITY_NORMAL, - TP_CALLBACK_PRIORITY_LOW, - TP_CALLBACK_PRIORITY_INVALID, - TP_CALLBACK_PRIORITY_COUNT = TP_CALLBACK_PRIORITY_INVALID -} TP_CALLBACK_PRIORITY; - typedef struct _TP_POOL_STACK_INFORMATION { SIZE_T StackReserve; @@ -77,40 +68,9 @@ typedef struct _TP_CALLBACK_ENVIRON_V1 } u; } TP_CALLBACK_ENVIRON_V1; -#endif +typedef TP_CALLBACK_ENVIRON_V1 TP_CALLBACK_ENVIRON, *PTP_CALLBACK_ENVIRON; -/* Non-Windows and pre Windows 7 */ -#if ((!defined(_WIN32)) || (defined(_WIN32) && (_WIN32_WINNT < 0x0601))) - -typedef struct _TP_CALLBACK_ENVIRON_V3 -{ - 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_PRIORITY CallbackPriority; - DWORD Size; -} TP_CALLBACK_ENVIRON_V3; - -//typedef TP_CALLBACK_ENVIRON_V3 TP_CALLBACK_ENVIRON, *PTP_CALLBACK_ENVIRON; - -#endif +#endif /* _WIN32 not defined */ typedef struct _TP_WORK TP_WORK, *PTP_WORK; typedef struct _TP_TIMER TP_TIMER, *PTP_TIMER; @@ -120,9 +80,6 @@ typedef struct _TP_WAIT TP_WAIT, *PTP_WAIT; typedef struct _TP_IO TP_IO, *PTP_IO; -#if !defined(_WIN32) || (defined(_WIN32) && (_WIN32_WINNT < 0x0601)) -typedef TP_CALLBACK_ENVIRON_V1 TP_CALLBACK_ENVIRON, *PTP_CALLBACK_ENVIRON; -#endif #ifndef _WIN32 @@ -153,7 +110,7 @@ typedef VOID (*PTP_WIN32_IO_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Cont #endif -#if (!defined(_WIN32) || ((defined(_WIN32) && (_WIN32_WINNT < 0x0601)))) +#if (!defined(_WIN32) || ((defined(_WIN32) && (_WIN32_WINNT < 0x0600)))) #define WINPR_THREAD_POOL 1 #endif @@ -209,14 +166,44 @@ WINPR_API VOID SetThreadpoolThreadMaximum(PTP_POOL ptpp, DWORD cthrdMost); /* Callback Environment */ -WINPR_API VOID InitializeThreadpoolEnvironment(PTP_CALLBACK_ENVIRON pcbe); -WINPR_API VOID DestroyThreadpoolEnvironment(PTP_CALLBACK_ENVIRON pcbe); -WINPR_API VOID SetThreadpoolCallbackPool(PTP_CALLBACK_ENVIRON pcbe, PTP_POOL ptpp); -WINPR_API VOID SetThreadpoolCallbackCleanupGroup(PTP_CALLBACK_ENVIRON pcbe, - PTP_CLEANUP_GROUP ptpcg, PTP_CLEANUP_GROUP_CANCEL_CALLBACK pfng); -WINPR_API VOID SetThreadpoolCallbackRunsLong(PTP_CALLBACK_ENVIRON pcbe); -WINPR_API VOID SetThreadpoolCallbackLibrary(PTP_CALLBACK_ENVIRON pcbe, PVOID mod); -WINPR_API VOID SetThreadpoolCallbackPriority(PTP_CALLBACK_ENVIRON pcbe, TP_CALLBACK_PRIORITY Priority); +static INLINE VOID InitializeThreadpoolEnvironment(PTP_CALLBACK_ENVIRON pcbe) +{ + pcbe->Version = 1; + pcbe->Pool = NULL; + pcbe->CleanupGroup = NULL; + pcbe->CleanupGroupCancelCallback = NULL; + pcbe->RaceDll = NULL; + pcbe->ActivationContext = NULL; + pcbe->FinalizationCallback = NULL; + pcbe->u.Flags = 0; +} + +static INLINE VOID DestroyThreadpoolEnvironment(PTP_CALLBACK_ENVIRON pcbe) +{ + /* no actions, this may change in a future release. */ +} + +static INLINE VOID SetThreadpoolCallbackPool(PTP_CALLBACK_ENVIRON pcbe, PTP_POOL ptpp) +{ + pcbe->Pool = ptpp; +} + +static INLINE VOID SetThreadpoolCallbackCleanupGroup(PTP_CALLBACK_ENVIRON pcbe, PTP_CLEANUP_GROUP ptpcg, PTP_CLEANUP_GROUP_CANCEL_CALLBACK pfng) +{ + pcbe->CleanupGroup = ptpcg; + pcbe->CleanupGroupCancelCallback = pfng; +} + +static INLINE VOID SetThreadpoolCallbackRunsLong(PTP_CALLBACK_ENVIRON pcbe) +{ + pcbe->u.s.LongFunction = 1; +} + +static INLINE VOID SetThreadpoolCallbackLibrary(PTP_CALLBACK_ENVIRON pcbe, PVOID mod) +{ + pcbe->RaceDll = mod; +} + /* Callback */ diff --git a/winpr/include/winpr/synch.h b/winpr/include/winpr/synch.h index d43a3ca98..6b15e7948 100644 --- a/winpr/include/winpr/synch.h +++ b/winpr/include/winpr/synch.h @@ -276,16 +276,8 @@ WINPR_API BOOL DeleteTimerQueueTimer(HANDLE TimerQueue, HANDLE Timer, HANDLE Com #endif -#if (defined(_WIN32) && defined(_SYNCHAPI_H_) && (_WIN32_WINNT < 0x0600)) -#define WINPR_INITIALIZE_CRITICAL_SECTION_EX 1 -#elif (defined(_WIN32) && (_WIN32_WINNT < 0x0403)) -#define WINPR_INITIALIZE_CRITICAL_SECTION_EX 1 -#endif - -#ifdef WINPR_INITIALIZE_CRITICAL_SECTION_EX - -WINPR_API BOOL InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags); - +#if (defined(_WIN32) && (_WIN32_WINNT < 0x0600)) +#define InitializeCriticalSectionEx(A,B,C) InitializeCriticalSectionAndSpinCount(A,B) #endif #ifndef _RTL_RUN_ONCE_DEF diff --git a/winpr/libwinpr/file/generic.c b/winpr/libwinpr/file/generic.c index 96d3c12a7..1f2dc0508 100644 --- a/winpr/libwinpr/file/generic.c +++ b/winpr/libwinpr/file/generic.c @@ -860,7 +860,7 @@ int UnixChangeFileMode(const char* filename, int flags) return -1; /* Check for unsupported flags. */ - if (flags & ~(_S_IREAD | _S_IWRITE) != 0) + if (flags & ~(_S_IREAD | _S_IWRITE)) WLog_WARN(TAG, "Unsupported file mode %d for _wchmod", flags); rc = _wchmod(wfl, flags); diff --git a/winpr/libwinpr/pool/CMakeLists.txt b/winpr/libwinpr/pool/CMakeLists.txt index fd70d7301..acd27c48e 100644 --- a/winpr/libwinpr/pool/CMakeLists.txt +++ b/winpr/libwinpr/pool/CMakeLists.txt @@ -23,7 +23,6 @@ winpr_module_add( cleanup_group.c pool.c pool.h - callback_environment.c callback.c callback_cleanup.c) diff --git a/winpr/libwinpr/pool/callback.c b/winpr/libwinpr/pool/callback.c index f521d9eda..630a78cec 100644 --- a/winpr/libwinpr/pool/callback.c +++ b/winpr/libwinpr/pool/callback.c @@ -25,44 +25,32 @@ #include #include +#ifdef WINPR_THREAD_POOL + #ifdef _WIN32 - -static BOOL module_initialized = FALSE; -static BOOL module_available = FALSE; -static HMODULE kernel32_module = NULL; - +static INIT_ONCE init_once_module = INIT_ONCE_STATIC_INIT; static BOOL (WINAPI * pCallbackMayRunLong)(PTP_CALLBACK_INSTANCE pci); -static void module_init() +static BOOL CALLBACK init_module(PINIT_ONCE once, PVOID param, PVOID *context) { - 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"); + HMODULE kernel32 = LoadLibraryA("kernel32.dll"); + if (kernel32) + { + pCallbackMayRunLong = (void*)GetProcAddress(kernel32, "CallbackMayRunLong"); + } + return TRUE; } - #endif -#ifdef WINPR_THREAD_POOL - BOOL CallbackMayRunLong(PTP_CALLBACK_INSTANCE pci) { #ifdef _WIN32 - module_init(); - + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); if (pCallbackMayRunLong) return pCallbackMayRunLong(pci); -#else #endif + /* No default implementation */ return FALSE; } -#endif +#endif /* WINPR_THREAD_POOL defined */ diff --git a/winpr/libwinpr/pool/callback_cleanup.c b/winpr/libwinpr/pool/callback_cleanup.c index 1403f3dc2..520b8ce12 100644 --- a/winpr/libwinpr/pool/callback_cleanup.c +++ b/winpr/libwinpr/pool/callback_cleanup.c @@ -27,12 +27,10 @@ #include "pool.h" +#ifdef WINPR_THREAD_POOL + #ifdef _WIN32 - -static BOOL module_initialized = FALSE; -static BOOL module_available = FALSE; -static HMODULE kernel32_module = NULL; - +static INIT_ONCE init_once_module = INIT_ONCE_STATIC_INIT; 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); @@ -40,96 +38,98 @@ static VOID (WINAPI * pLeaveCriticalSectionWhenCallbackReturns)(PTP_CALLBACK_INS static VOID (WINAPI * pFreeLibraryWhenCallbackReturns)(PTP_CALLBACK_INSTANCE pci, HMODULE mod); static VOID (WINAPI * pDisassociateCurrentThreadFromCallback)(PTP_CALLBACK_INSTANCE pci); -static void module_init() +static BOOL CALLBACK init_module(PINIT_ONCE once, PVOID param, PVOID *context) { - if (module_initialized) - return; - - kernel32_module = LoadLibraryA("kernel32.dll"); - module_initialized = TRUE; - - if (!kernel32_module) - return; - - 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"); + HMODULE kernel32 = LoadLibraryA("kernel32.dll"); + if (kernel32) + { + pSetEventWhenCallbackReturns = (void*)GetProcAddress(kernel32, "SetEventWhenCallbackReturns"); + pReleaseSemaphoreWhenCallbackReturns = (void*)GetProcAddress(kernel32, "ReleaseSemaphoreWhenCallbackReturns"); + pReleaseMutexWhenCallbackReturns = (void*)GetProcAddress(kernel32, "ReleaseMutexWhenCallbackReturns"); + pLeaveCriticalSectionWhenCallbackReturns = (void*)GetProcAddress(kernel32, "LeaveCriticalSectionWhenCallbackReturns"); + pFreeLibraryWhenCallbackReturns = (void*)GetProcAddress(kernel32, "FreeLibraryWhenCallbackReturns"); + pDisassociateCurrentThreadFromCallback = (void*)GetProcAddress(kernel32, "DisassociateCurrentThreadFromCallback"); + } + return TRUE; } - #endif -#ifdef WINPR_THREAD_POOL - VOID SetEventWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE evt) { #ifdef _WIN32 - module_init(); - + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); if (pSetEventWhenCallbackReturns) + { pSetEventWhenCallbackReturns(pci, evt); -#else + return; + } #endif + /* No default implementation */ } VOID ReleaseSemaphoreWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE sem, DWORD crel) { #ifdef _WIN32 - module_init(); - + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); if (pReleaseSemaphoreWhenCallbackReturns) + { pReleaseSemaphoreWhenCallbackReturns(pci, sem, crel); -#else + return; + } #endif + /* No default implementation */ } VOID ReleaseMutexWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE mut) { #ifdef _WIN32 - module_init(); - + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); if (pReleaseMutexWhenCallbackReturns) + { pReleaseMutexWhenCallbackReturns(pci, mut); -#else + return; + } #endif + /* No default implementation */ } VOID LeaveCriticalSectionWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, PCRITICAL_SECTION pcs) { #ifdef _WIN32 - module_init(); - + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); if (pLeaveCriticalSectionWhenCallbackReturns) + { pLeaveCriticalSectionWhenCallbackReturns(pci, pcs); -#else + } #endif + /* No default implementation */ } VOID FreeLibraryWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HMODULE mod) { #ifdef _WIN32 - module_init(); - + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); if (pFreeLibraryWhenCallbackReturns) + { pFreeLibraryWhenCallbackReturns(pci, mod); -#else + return; + } #endif + /* No default implementation */ } VOID DisassociateCurrentThreadFromCallback(PTP_CALLBACK_INSTANCE pci) { #ifdef _WIN32 - module_init(); - + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); if (pDisassociateCurrentThreadFromCallback) + { pDisassociateCurrentThreadFromCallback(pci); -#else + return; + } #endif + /* No default implementation */ } -#endif +#endif /* WINPR_THREAD_POOL defined */ diff --git a/winpr/libwinpr/pool/callback_environment.c b/winpr/libwinpr/pool/callback_environment.c deleted file mode 100644 index 5873a46d0..000000000 --- a/winpr/libwinpr/pool/callback_environment.c +++ /dev/null @@ -1,204 +0,0 @@ -/** - * WinPR: Windows Portable Runtime - * Thread Pool API (Callback Environment) - * - * Copyright 2012 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#include "pool.h" - -#ifdef WINPR_THREAD_POOL - -VOID InitializeCallbackEnvironment_V1(TP_CALLBACK_ENVIRON_V1* pcbe) -{ - pcbe->Version = 1; - - pcbe->Pool = NULL; - pcbe->CleanupGroup = NULL; - pcbe->CleanupGroupCancelCallback = NULL; - pcbe->RaceDll = NULL; - pcbe->ActivationContext = NULL; - pcbe->FinalizationCallback = NULL; - pcbe->u.Flags = 0; -} - -VOID InitializeCallbackEnvironment_V3(TP_CALLBACK_ENVIRON_V3* pcbe) -{ - pcbe->Version = 3; - - pcbe->Pool = NULL; - pcbe->CleanupGroup = NULL; - pcbe->CleanupGroupCancelCallback = NULL; - pcbe->RaceDll = NULL; - pcbe->ActivationContext = NULL; - pcbe->FinalizationCallback = NULL; - pcbe->u.Flags = 0; - - pcbe->CallbackPriority = TP_CALLBACK_PRIORITY_NORMAL; - pcbe->Size = sizeof(TP_CALLBACK_ENVIRON); -} - -#endif - -#ifdef _WIN32 - -static BOOL module_initialized = FALSE; -static BOOL module_available = FALSE; -static HMODULE kernel32_module = NULL; - -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; - - /* InitializeThreadpoolEnvironment is an inline function */ - 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 = -{ - 1, /* Version */ - NULL, /* Pool */ - NULL, /* CleanupGroup */ - NULL, /* CleanupGroupCancelCallback */ - NULL, /* RaceDll */ - NULL, /* ActivationContext */ - NULL, /* FinalizationCallback */ - { 0 } /* Flags */ -}; - -PTP_CALLBACK_ENVIRON GetDefaultThreadpoolEnvironment() -{ - PTP_CALLBACK_ENVIRON environment = &DEFAULT_CALLBACK_ENVIRONMENT; - - environment->Pool = GetDefaultThreadpool(); - - return environment; -} - -#endif - -#ifdef WINPR_THREAD_POOL - -VOID InitializeThreadpoolEnvironment(PTP_CALLBACK_ENVIRON pcbe) -{ - if (pcbe->Version == 3) - InitializeCallbackEnvironment_V3((TP_CALLBACK_ENVIRON_V3*) pcbe); - else - InitializeCallbackEnvironment_V1(pcbe); -} - -VOID DestroyThreadpoolEnvironment(PTP_CALLBACK_ENVIRON pcbe) -{ -#ifdef _WIN32 - module_init(); - - if (pDestroyThreadpoolEnvironment) - pDestroyThreadpoolEnvironment(pcbe); -#else -#endif -} - -VOID SetThreadpoolCallbackPool(PTP_CALLBACK_ENVIRON pcbe, PTP_POOL ptpp) -{ -#ifdef _WIN32 - module_init(); - - if (pSetThreadpoolCallbackPool) - pSetThreadpoolCallbackPool(pcbe, ptpp); -#else - pcbe->Pool = ptpp; -#endif -} - -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; -#endif -} - -VOID SetThreadpoolCallbackRunsLong(PTP_CALLBACK_ENVIRON pcbe) -{ -#ifdef _WIN32 - module_init(); - - if (pSetThreadpoolCallbackRunsLong) - pSetThreadpoolCallbackRunsLong(pcbe); -#else - pcbe->u.s.LongFunction = TRUE; -#endif -} - -VOID SetThreadpoolCallbackLibrary(PTP_CALLBACK_ENVIRON pcbe, PVOID mod) -{ -#ifdef _WIN32 - module_init(); - - if (pSetThreadpoolCallbackLibrary) - pSetThreadpoolCallbackLibrary(pcbe, mod); -#else -#endif -} - -VOID SetThreadpoolCallbackPriority(PTP_CALLBACK_ENVIRON pcbe, TP_CALLBACK_PRIORITY Priority) -{ -#ifdef _WIN32 - module_init(); - - if (pSetThreadpoolCallbackPriority) - pSetThreadpoolCallbackPriority(pcbe, Priority); -#else -#endif -} - -#endif diff --git a/winpr/libwinpr/pool/cleanup_group.c b/winpr/libwinpr/pool/cleanup_group.c index bf884564d..8b9a89d8f 100644 --- a/winpr/libwinpr/pool/cleanup_group.c +++ b/winpr/libwinpr/pool/cleanup_group.c @@ -27,75 +27,64 @@ #include "pool.h" +#ifdef WINPR_THREAD_POOL + #ifdef _WIN32 - -static BOOL module_initialized = FALSE; -static BOOL module_available = FALSE; -static HMODULE kernel32_module = NULL; - +static INIT_ONCE init_once_module = INIT_ONCE_STATIC_INIT; 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() +static BOOL CALLBACK init_module(PINIT_ONCE once, PVOID param, PVOID *context) { - 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"); + HMODULE kernel32 = LoadLibraryA("kernel32.dll"); + if (kernel32) + { + pCreateThreadpoolCleanupGroup = (void*)GetProcAddress(kernel32, "CreateThreadpoolCleanupGroup"); + pCloseThreadpoolCleanupGroupMembers = (void*)GetProcAddress(kernel32, "CloseThreadpoolCleanupGroupMembers"); + pCloseThreadpoolCleanupGroup = (void*)GetProcAddress(kernel32, "CloseThreadpoolCleanupGroup"); + } + return TRUE; } - #endif -#if WINPR_THREAD_POOL - PTP_CLEANUP_GROUP CreateThreadpoolCleanupGroup() { PTP_CLEANUP_GROUP cleanupGroup = NULL; #ifdef _WIN32 - module_init(); - + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); if (pCreateThreadpoolCleanupGroup) return pCreateThreadpoolCleanupGroup(); -#else - cleanupGroup = (PTP_CLEANUP_GROUP) malloc(sizeof(TP_CLEANUP_GROUP)); #endif + cleanupGroup = (PTP_CLEANUP_GROUP) malloc(sizeof(TP_CLEANUP_GROUP)); return cleanupGroup; } VOID CloseThreadpoolCleanupGroupMembers(PTP_CLEANUP_GROUP ptpcg, BOOL fCancelPendingCallbacks, PVOID pvCleanupContext) { #ifdef _WIN32 - module_init(); - + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); if (pCloseThreadpoolCleanupGroupMembers) + { pCloseThreadpoolCleanupGroupMembers(ptpcg, fCancelPendingCallbacks, pvCleanupContext); -#else - + return; + } #endif + /* No default implementation */ } VOID CloseThreadpoolCleanupGroup(PTP_CLEANUP_GROUP ptpcg) { #ifdef _WIN32 - module_init(); - + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); if (pCloseThreadpoolCleanupGroup) + { pCloseThreadpoolCleanupGroup(ptpcg); -#else - free(ptpcg); + return; + } #endif + free(ptpcg); } -#endif +#endif /* WINPR_THREAD_POOL defined */ diff --git a/winpr/libwinpr/pool/pool.c b/winpr/libwinpr/pool/pool.c index fa9e2f597..67bb8f742 100644 --- a/winpr/libwinpr/pool/pool.c +++ b/winpr/libwinpr/pool/pool.c @@ -27,37 +27,28 @@ #include "pool.h" +#ifdef WINPR_THREAD_POOL + #ifdef _WIN32 - -static BOOL module_initialized = FALSE; -static BOOL module_available = FALSE; -static HMODULE kernel32_module = NULL; - +static INIT_ONCE init_once_module = INIT_ONCE_STATIC_INIT; static PTP_POOL (WINAPI * pCreateThreadpool)(PVOID reserved); static VOID (WINAPI * pCloseThreadpool)(PTP_POOL ptpp); static BOOL (WINAPI * pSetThreadpoolThreadMinimum)(PTP_POOL ptpp, DWORD cthrdMic); static VOID (WINAPI * pSetThreadpoolThreadMaximum)(PTP_POOL ptpp, DWORD cthrdMost); -static void module_init() +static BOOL CALLBACK init_module(PINIT_ONCE once, PVOID param, PVOID *context) { - if (module_initialized) - return; - - kernel32_module = LoadLibraryA("kernel32.dll"); - module_initialized = TRUE; - - if (!kernel32_module) - return; - - module_available = TRUE; - - pCreateThreadpool = (void*) GetProcAddress(kernel32_module, "CreateThreadpool"); - pCloseThreadpool = (void*) GetProcAddress(kernel32_module, "CloseThreadpool"); - pSetThreadpoolThreadMinimum = (void*) GetProcAddress(kernel32_module, "SetThreadpoolThreadMinimum"); - pSetThreadpoolThreadMaximum = (void*) GetProcAddress(kernel32_module, "SetThreadpoolThreadMaximum"); + HMODULE kernel32 = LoadLibraryA("kernel32.dll"); + if (kernel32) + { + pCreateThreadpool = (void*)GetProcAddress(kernel32, "CreateThreadpool"); + pCloseThreadpool = (void*)GetProcAddress(kernel32, "CloseThreadpool"); + pSetThreadpoolThreadMinimum = (void*)GetProcAddress(kernel32, "SetThreadpoolThreadMinimum"); + pSetThreadpoolThreadMaximum = (void*)GetProcAddress(kernel32, "SetThreadpoolThreadMaximum"); + } + return TRUE; } - -#else +#endif static TP_POOL DEFAULT_POOL = { @@ -169,7 +160,6 @@ fail_countdown_event: fail_queue_new: return FALSE; - } PTP_POOL GetDefaultThreadpool() @@ -184,20 +174,14 @@ PTP_POOL GetDefaultThreadpool() return pool; } -#endif - -#ifdef WINPR_THREAD_POOL - PTP_POOL CreateThreadpool(PVOID reserved) { PTP_POOL pool = NULL; - #ifdef _WIN32 - module_init(); - + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); if (pCreateThreadpool) return pCreateThreadpool(reserved); -#else +#endif if (!(pool = (PTP_POOL) calloc(1, sizeof(TP_POOL)))) return NULL; @@ -206,7 +190,6 @@ PTP_POOL CreateThreadpool(PVOID reserved) free(pool); return NULL; } -#endif return pool; } @@ -214,11 +197,13 @@ PTP_POOL CreateThreadpool(PVOID reserved) VOID CloseThreadpool(PTP_POOL ptpp) { #ifdef _WIN32 - module_init(); - + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); if (pCloseThreadpool) + { pCloseThreadpool(ptpp); -#else + return; + } +#endif SetEvent(ptpp->TerminateEvent); ArrayList_Free(ptpp->Threads); @@ -237,19 +222,16 @@ VOID CloseThreadpool(PTP_POOL ptpp) { free(ptpp); } -#endif } BOOL SetThreadpoolThreadMinimum(PTP_POOL ptpp, DWORD cthrdMic) { + HANDLE thread; #ifdef _WIN32 - module_init(); - + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); if (pSetThreadpoolThreadMinimum) return pSetThreadpoolThreadMinimum(ptpp, cthrdMic); -#else - HANDLE thread; - +#endif ptpp->Minimum = cthrdMic; while (ArrayList_Count(ptpp->Threads) < ptpp->Minimum) @@ -264,27 +246,21 @@ BOOL SetThreadpoolThreadMinimum(PTP_POOL ptpp, DWORD cthrdMic) if (ArrayList_Add(ptpp->Threads, thread) < 0) return FALSE; } -#endif + return TRUE; } VOID SetThreadpoolThreadMaximum(PTP_POOL ptpp, DWORD cthrdMost) { #ifdef _WIN32 - module_init(); - + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); if (pSetThreadpoolThreadMaximum) + { pSetThreadpoolThreadMaximum(ptpp, cthrdMost); -#else + return; + } +#endif ptpp->Maximum = cthrdMost; -#endif } -#endif - -/* dummy */ - -void winpr_pool_dummy() -{ - -} +#endif /* WINPR_THREAD_POOL defined */ diff --git a/winpr/libwinpr/pool/pool.h b/winpr/libwinpr/pool/pool.h index 5c675282e..e84635fc9 100644 --- a/winpr/libwinpr/pool/pool.h +++ b/winpr/libwinpr/pool/pool.h @@ -67,12 +67,7 @@ struct _TP_CLEANUP_GROUP void* dummy; }; -#ifndef _WIN32 - -PTP_POOL GetDefaultThreadpool(void); -PTP_CALLBACK_ENVIRON GetDefaultThreadpoolEnvironment(void); - -#endif +PTP_POOL GetDefaultThreadpool(); #endif /* WINPR_POOL_PRIVATE_H */ diff --git a/winpr/libwinpr/pool/test/TestPoolWork.c b/winpr/libwinpr/pool/test/TestPoolWork.c index 08b4c9af1..67c80da89 100644 --- a/winpr/libwinpr/pool/test/TestPoolWork.c +++ b/winpr/libwinpr/pool/test/TestPoolWork.c @@ -12,7 +12,7 @@ void CALLBACK test_WorkCallback(PTP_CALLBACK_INSTANCE instance, void* context, P BYTE b[1024]; BYTE c[1024]; - printf("Hello %s: %d (thread: %d)\n", (char*) context, + printf("Hello %s: %3d (thread: 0x%08X)\n", (char*) context, InterlockedIncrement(&count), GetCurrentThreadId()); for (index = 0; index < 100; index++) @@ -104,7 +104,16 @@ int TestPoolWork(int argc, char* argv[]) DestroyThreadpoolEnvironment(&environment); - CloseThreadpoolWork(work); + /** + * See Remarks at https://msdn.microsoft.com/en-us/library/windows/desktop/ms682043(v=vs.85).aspx + * If there is a cleanup group associated with the work object, + * it is not necessary to call CloseThreadpoolWork ! + * calling the CloseThreadpoolCleanupGroupMembers function releases the work, wait, + * and timer objects associated with the cleanup group. + */ + + /* CloseThreadpoolWork(work); // this would segfault, see comment above. */ + CloseThreadpool(pool); return 0; diff --git a/winpr/libwinpr/pool/work.c b/winpr/libwinpr/pool/work.c index ab5328cdf..2e32d2181 100644 --- a/winpr/libwinpr/pool/work.c +++ b/winpr/libwinpr/pool/work.c @@ -29,92 +29,93 @@ #include "../log.h" #define TAG WINPR_TAG("pool") +#ifdef WINPR_THREAD_POOL + #ifdef _WIN32 - -static BOOL module_initialized = FALSE; -static BOOL module_available = FALSE; -static HMODULE kernel32_module = NULL; - +static INIT_ONCE init_once_module = INIT_ONCE_STATIC_INIT; 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() +static BOOL CALLBACK init_module(PINIT_ONCE once, PVOID param, PVOID *context) { - if (module_initialized) - return; - - kernel32_module = LoadLibraryA("kernel32.dll"); - module_initialized = TRUE; - - 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"); + HMODULE kernel32 = LoadLibraryA("kernel32.dll"); + if (kernel32) + { + pCreateThreadpoolWork = (void*)GetProcAddress(kernel32, "CreateThreadpoolWork"); + pCloseThreadpoolWork = (void*)GetProcAddress(kernel32, "CloseThreadpoolWork"); + pSubmitThreadpoolWork = (void*)GetProcAddress(kernel32, "SubmitThreadpoolWork"); + pTrySubmitThreadpoolCallback = (void*)GetProcAddress(kernel32, "TrySubmitThreadpoolCallback"); + pWaitForThreadpoolWorkCallbacks = (void*)GetProcAddress(kernel32, "WaitForThreadpoolWorkCallbacks"); + } + return TRUE; } - #endif -#ifdef WINPR_THREAD_POOL +static TP_CALLBACK_ENVIRON DEFAULT_CALLBACK_ENVIRONMENT = +{ + 1, /* Version */ + NULL, /* Pool */ + NULL, /* CleanupGroup */ + NULL, /* CleanupGroupCancelCallback */ + NULL, /* RaceDll */ + NULL, /* ActivationContext */ + NULL, /* FinalizationCallback */ + { 0 } /* Flags */ +}; PTP_WORK CreateThreadpoolWork(PTP_WORK_CALLBACK pfnwk, PVOID pv, PTP_CALLBACK_ENVIRON pcbe) { PTP_WORK work = NULL; #ifdef _WIN32 - module_init(); - + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); if (pCreateThreadpoolWork) return pCreateThreadpoolWork(pfnwk, pv, pcbe); - -#else +#endif work = (PTP_WORK) malloc(sizeof(TP_WORK)); if (work) { + if (!pcbe) + { + pcbe = &DEFAULT_CALLBACK_ENVIRONMENT; + pcbe->Pool = GetDefaultThreadpool(); + } + work->CallbackEnvironment = pcbe; work->WorkCallback = pfnwk; work->CallbackParameter = pv; - - if (!pcbe) - pcbe = GetDefaultThreadpoolEnvironment(); - - work->CallbackEnvironment = pcbe; } -#endif return work; } VOID CloseThreadpoolWork(PTP_WORK pwk) { #ifdef _WIN32 - module_init(); - + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); if (pCloseThreadpoolWork) + { pCloseThreadpoolWork(pwk); - -#else - free(pwk); + return; + } #endif + free(pwk); } VOID SubmitThreadpoolWork(PTP_WORK pwk) { -#ifdef _WIN32 - module_init(); - - if (pSubmitThreadpoolWork) - pSubmitThreadpoolWork(pwk); - -#else PTP_POOL pool; PTP_CALLBACK_INSTANCE callbackInstance; +#ifdef _WIN32 + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); + if (pSubmitThreadpoolWork) + { + pSubmitThreadpoolWork(pwk); + return; + } +#endif pool = pwk->CallbackEnvironment->Pool; callbackInstance = (PTP_CALLBACK_INSTANCE) malloc(sizeof(TP_CALLBACK_INSTANCE)); @@ -124,41 +125,36 @@ VOID SubmitThreadpoolWork(PTP_WORK pwk) CountdownEvent_AddCount(pool->WorkComplete, 1); Queue_Enqueue(pool->PendingQueue, callbackInstance); } - -#endif } BOOL TrySubmitThreadpoolCallback(PTP_SIMPLE_CALLBACK pfns, PVOID pv, PTP_CALLBACK_ENVIRON pcbe) { #ifdef _WIN32 - module_init(); - + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); if (pTrySubmitThreadpoolCallback) return pTrySubmitThreadpoolCallback(pfns, pv, pcbe); - -#else #endif + WLog_ERR(TAG, "TrySubmitThreadpoolCallback is not implemented"); return FALSE; } VOID WaitForThreadpoolWorkCallbacks(PTP_WORK pwk, BOOL fCancelPendingCallbacks) { -#ifdef _WIN32 - module_init(); - - if (pWaitForThreadpoolWorkCallbacks) - pWaitForThreadpoolWorkCallbacks(pwk, fCancelPendingCallbacks); - -#else HANDLE event; PTP_POOL pool; +#ifdef _WIN32 + InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL); + if (pWaitForThreadpoolWorkCallbacks) + { + pWaitForThreadpoolWorkCallbacks(pwk, fCancelPendingCallbacks); + return; + } +#endif pool = pwk->CallbackEnvironment->Pool; event = CountdownEvent_WaitHandle(pool->WorkComplete); if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0) WLog_ERR(TAG, "error waiting on work completion"); - -#endif } -#endif +#endif /* WINPR_THREAD_POOL defined */ diff --git a/winpr/libwinpr/synch/critical.c b/winpr/libwinpr/synch/critical.c index bc2f3de0a..fe2fdfecb 100644 --- a/winpr/libwinpr/synch/critical.c +++ b/winpr/libwinpr/synch/critical.c @@ -247,48 +247,3 @@ VOID DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection) } #endif - -#ifdef WINPR_INITIALIZE_CRITICAL_SECTION_EX - -typedef BOOL (WINAPI* PINITIALIZE_CRITICAL_SECTION_EX_FN)(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags); - -static HMODULE g_KERNEL32_Library = NULL; -static BOOL g_InitializeCriticalSectionEx_Detected = FALSE; -static BOOL g_InitializeCriticalSectionEx_Available = FALSE; -static PINITIALIZE_CRITICAL_SECTION_EX_FN g_pInitializeCriticalSectionEx = NULL; - -BOOL InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags) -{ - if (!g_InitializeCriticalSectionEx_Detected) - { - g_KERNEL32_Library = LoadLibrary(_T("kernel32.dll")); - - if (g_KERNEL32_Library) - { - g_pInitializeCriticalSectionEx = (PINITIALIZE_CRITICAL_SECTION_EX_FN) - GetProcAddress(g_KERNEL32_Library, "InitializeCriticalSectionEx"); - g_InitializeCriticalSectionEx_Available = (g_pInitializeCriticalSectionEx) ? TRUE : FALSE; - } - else - { - g_InitializeCriticalSectionEx_Available = FALSE; - } - - g_InitializeCriticalSectionEx_Detected = TRUE; - } - - if (g_InitializeCriticalSectionEx_Available) - { - /* Vista and later */ - return (*g_pInitializeCriticalSectionEx)(lpCriticalSection, dwSpinCount, Flags); - } - else - { - /* Windows XP */ - InitializeCriticalSection(lpCriticalSection); - } - - return TRUE; -} - -#endif