pool.h (10219B)
1/** 2 * WinPR: Windows Portable Runtime 3 * Thread Pool API 4 * 5 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20#ifndef WINPR_POOL_H 21#define WINPR_POOL_H 22 23#include <winpr/winpr.h> 24#include <winpr/wtypes.h> 25 26#include <winpr/synch.h> 27#include <winpr/thread.h> 28 29#ifndef _WIN32 30 31typedef DWORD TP_VERSION, *PTP_VERSION; 32 33typedef struct _TP_CALLBACK_INSTANCE TP_CALLBACK_INSTANCE, *PTP_CALLBACK_INSTANCE; 34 35typedef VOID (*PTP_SIMPLE_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context); 36 37typedef struct _TP_POOL TP_POOL, *PTP_POOL; 38 39typedef struct _TP_POOL_STACK_INFORMATION 40{ 41 SIZE_T StackReserve; 42 SIZE_T StackCommit; 43} TP_POOL_STACK_INFORMATION, *PTP_POOL_STACK_INFORMATION; 44 45typedef struct _TP_CLEANUP_GROUP TP_CLEANUP_GROUP, *PTP_CLEANUP_GROUP; 46 47typedef VOID (*PTP_CLEANUP_GROUP_CANCEL_CALLBACK)(PVOID ObjectContext, PVOID CleanupContext); 48 49typedef struct _TP_CALLBACK_ENVIRON_V1 50{ 51 TP_VERSION Version; 52 PTP_POOL Pool; 53 PTP_CLEANUP_GROUP CleanupGroup; 54 PTP_CLEANUP_GROUP_CANCEL_CALLBACK CleanupGroupCancelCallback; 55 PVOID RaceDll; 56 struct _ACTIVATION_CONTEXT* ActivationContext; 57 PTP_SIMPLE_CALLBACK FinalizationCallback; 58 59 union { 60 DWORD Flags; 61 struct 62 { 63 DWORD LongFunction : 1; 64 DWORD Persistent : 1; 65 DWORD Private : 30; 66 } s; 67 } u; 68} TP_CALLBACK_ENVIRON_V1; 69 70typedef TP_CALLBACK_ENVIRON_V1 TP_CALLBACK_ENVIRON, *PTP_CALLBACK_ENVIRON; 71 72#endif /* _WIN32 not defined */ 73 74typedef struct _TP_WORK TP_WORK, *PTP_WORK; 75typedef struct _TP_TIMER TP_TIMER, *PTP_TIMER; 76 77typedef DWORD TP_WAIT_RESULT; 78typedef struct _TP_WAIT TP_WAIT, *PTP_WAIT; 79 80typedef struct _TP_IO TP_IO, *PTP_IO; 81 82#ifndef _WIN32 83 84typedef VOID (*PTP_WORK_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK Work); 85typedef VOID (*PTP_TIMER_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_TIMER Timer); 86typedef VOID (*PTP_WAIT_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WAIT Wait, 87 TP_WAIT_RESULT WaitResult); 88 89#endif 90 91/* 92There is a bug in the Win8 header that defines the IO 93callback unconditionally. Versions of Windows greater 94than XP will conditionally define it. The following 95logic tries to fix that. 96*/ 97#ifdef _THREADPOOLAPISET_H_ 98#define PTP_WIN32_IO_CALLBACK_DEFINED 1 99#else 100#if (_WIN32_WINNT >= 0x0600) 101#define PTP_WIN32_IO_CALLBACK_DEFINED 1 102#endif 103#endif 104 105#ifndef PTP_WIN32_IO_CALLBACK_DEFINED 106 107typedef VOID (*PTP_WIN32_IO_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, 108 PVOID Overlapped, ULONG IoResult, 109 ULONG_PTR NumberOfBytesTransferred, PTP_IO Io); 110 111#endif 112 113#if (!defined(_WIN32) || ((defined(_WIN32) && (_WIN32_WINNT < 0x0600)))) 114#define WINPR_THREAD_POOL 1 115#endif 116 117#ifdef __cplusplus 118extern "C" 119{ 120#endif 121 122 /* Synch */ 123 124#ifdef WINPR_THREAD_POOL 125 126 WINPR_API PTP_WAIT winpr_CreateThreadpoolWait(PTP_WAIT_CALLBACK pfnwa, PVOID pv, 127 PTP_CALLBACK_ENVIRON pcbe); 128 WINPR_API VOID winpr_CloseThreadpoolWait(PTP_WAIT pwa); 129 WINPR_API VOID winpr_SetThreadpoolWait(PTP_WAIT pwa, HANDLE h, PFILETIME pftTimeout); 130 WINPR_API VOID winpr_WaitForThreadpoolWaitCallbacks(PTP_WAIT pwa, BOOL fCancelPendingCallbacks); 131 132#define CreateThreadpoolWait winpr_CreateThreadpoolWait 133#define CloseThreadpoolWait winpr_CloseThreadpoolWait 134#define SetThreadpoolWait winpr_SetThreadpoolWait 135#define WaitForThreadpoolWaitCallbacks winpr_WaitForThreadpoolWaitCallbacks 136 137 /* Work */ 138 139 WINPR_API PTP_WORK winpr_CreateThreadpoolWork(PTP_WORK_CALLBACK pfnwk, PVOID pv, 140 PTP_CALLBACK_ENVIRON pcbe); 141 WINPR_API VOID winpr_CloseThreadpoolWork(PTP_WORK pwk); 142 WINPR_API VOID winpr_SubmitThreadpoolWork(PTP_WORK pwk); 143 WINPR_API BOOL winpr_TrySubmitThreadpoolCallback(PTP_SIMPLE_CALLBACK pfns, PVOID pv, 144 PTP_CALLBACK_ENVIRON pcbe); 145 WINPR_API VOID winpr_WaitForThreadpoolWorkCallbacks(PTP_WORK pwk, BOOL fCancelPendingCallbacks); 146 147#define CreateThreadpoolWork winpr_CreateThreadpoolWork 148#define CloseThreadpoolWork winpr_CloseThreadpoolWork 149#define SubmitThreadpoolWork winpr_SubmitThreadpoolWork 150#define TrySubmitThreadpoolCallback winpr_TrySubmitThreadpoolCallback 151#define WaitForThreadpoolWorkCallbacks winpr_WaitForThreadpoolWorkCallbacks 152 153 /* Timer */ 154 155 WINPR_API PTP_TIMER winpr_CreateThreadpoolTimer(PTP_TIMER_CALLBACK pfnti, PVOID pv, 156 PTP_CALLBACK_ENVIRON pcbe); 157 WINPR_API VOID winpr_CloseThreadpoolTimer(PTP_TIMER pti); 158 WINPR_API BOOL winpr_IsThreadpoolTimerSet(PTP_TIMER pti); 159 WINPR_API VOID winpr_SetThreadpoolTimer(PTP_TIMER pti, PFILETIME pftDueTime, DWORD msPeriod, 160 DWORD msWindowLength); 161 WINPR_API VOID winpr_WaitForThreadpoolTimerCallbacks(PTP_TIMER pti, 162 BOOL fCancelPendingCallbacks); 163 164#define CreateThreadpoolTimer winpr_CreateThreadpoolTimer 165#define CloseThreadpoolTimer winpr_CloseThreadpoolTimer 166#define IsThreadpoolTimerSet winpr_IsThreadpoolTimerSet 167#define SetThreadpoolTimer winpr_SetThreadpoolTimer 168#define WaitForThreadpoolTimerCallbacks winpr_WaitForThreadpoolTimerCallbacks 169 170 /* I/O */ 171 172 WINPR_API PTP_IO winpr_CreateThreadpoolIo(HANDLE fl, PTP_WIN32_IO_CALLBACK pfnio, PVOID pv, 173 PTP_CALLBACK_ENVIRON pcbe); 174 WINPR_API VOID winpr_CloseThreadpoolIo(PTP_IO pio); 175 WINPR_API VOID winpr_StartThreadpoolIo(PTP_IO pio); 176 WINPR_API VOID winpr_CancelThreadpoolIo(PTP_IO pio); 177 WINPR_API VOID winpr_WaitForThreadpoolIoCallbacks(PTP_IO pio, BOOL fCancelPendingCallbacks); 178 179#define CreateThreadpoolIo winpr_CreateThreadpoolIo 180#define CloseThreadpoolIo winpr_CloseThreadpoolIo 181#define StartThreadpoolIo winpr_StartThreadpoolIo 182#define CancelThreadpoolIo winpr_CancelThreadpoolIo 183#define WaitForThreadpoolIoCallbacks winpr_WaitForThreadpoolIoCallbacks 184 185 /* Clean-up Group */ 186 187 WINPR_API VOID winpr_SetThreadpoolCallbackCleanupGroup(PTP_CALLBACK_ENVIRON pcbe, 188 PTP_CLEANUP_GROUP ptpcg, 189 PTP_CLEANUP_GROUP_CANCEL_CALLBACK pfng); 190 WINPR_API PTP_CLEANUP_GROUP winpr_CreateThreadpoolCleanupGroup(void); 191 WINPR_API VOID winpr_CloseThreadpoolCleanupGroupMembers(PTP_CLEANUP_GROUP ptpcg, 192 BOOL fCancelPendingCallbacks, 193 PVOID pvCleanupContext); 194 WINPR_API VOID winpr_CloseThreadpoolCleanupGroup(PTP_CLEANUP_GROUP ptpcg); 195 196#define SetThreadpoolCallbackCleanupGroup winpr_SetThreadpoolCallbackCleanupGroup 197#define CreateThreadpoolCleanupGroup winpr_CreateThreadpoolCleanupGroup 198#define CloseThreadpoolCleanupGroupMembers winpr_CloseThreadpoolCleanupGroupMembers 199#define CloseThreadpoolCleanupGroup winpr_CloseThreadpoolCleanupGroup 200 201 /* Pool */ 202 203 WINPR_API PTP_POOL winpr_CreateThreadpool(PVOID reserved); 204 WINPR_API VOID winpr_CloseThreadpool(PTP_POOL ptpp); 205 WINPR_API BOOL winpr_SetThreadpoolThreadMinimum(PTP_POOL ptpp, DWORD cthrdMic); 206 WINPR_API VOID winpr_SetThreadpoolThreadMaximum(PTP_POOL ptpp, DWORD cthrdMost); 207 208#define CreateThreadpool winpr_CreateThreadpool 209#define CloseThreadpool winpr_CloseThreadpool 210#define SetThreadpoolThreadMinimum winpr_SetThreadpoolThreadMinimum 211#define SetThreadpoolThreadMaximum winpr_SetThreadpoolThreadMaximum 212 213 /* Callback Environment */ 214 215 static INLINE VOID InitializeThreadpoolEnvironment(PTP_CALLBACK_ENVIRON pcbe) 216 { 217 pcbe->Version = 1; 218 pcbe->Pool = NULL; 219 pcbe->CleanupGroup = NULL; 220 pcbe->CleanupGroupCancelCallback = NULL; 221 pcbe->RaceDll = NULL; 222 pcbe->ActivationContext = NULL; 223 pcbe->FinalizationCallback = NULL; 224 pcbe->u.Flags = 0; 225 } 226 227 static INLINE VOID DestroyThreadpoolEnvironment(PTP_CALLBACK_ENVIRON pcbe) 228 { 229 /* no actions, this may change in a future release. */ 230 } 231 232 static INLINE VOID SetThreadpoolCallbackPool(PTP_CALLBACK_ENVIRON pcbe, PTP_POOL ptpp) 233 { 234 pcbe->Pool = ptpp; 235 } 236 237 static INLINE VOID SetThreadpoolCallbackRunsLong(PTP_CALLBACK_ENVIRON pcbe) 238 { 239 pcbe->u.s.LongFunction = 1; 240 } 241 242 static INLINE VOID SetThreadpoolCallbackLibrary(PTP_CALLBACK_ENVIRON pcbe, PVOID mod) 243 { 244 pcbe->RaceDll = mod; 245 } 246 247 /* Callback */ 248 249 WINPR_API BOOL winpr_CallbackMayRunLong(PTP_CALLBACK_INSTANCE pci); 250 251 /* Callback Clean-up */ 252 253 WINPR_API VOID winpr_SetEventWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE evt); 254 WINPR_API VOID winpr_ReleaseSemaphoreWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE sem, 255 DWORD crel); 256 WINPR_API VOID winpr_ReleaseMutexWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE mut); 257 WINPR_API VOID winpr_LeaveCriticalSectionWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, 258 PCRITICAL_SECTION pcs); 259 WINPR_API VOID winpr_FreeLibraryWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HMODULE mod); 260 WINPR_API VOID winpr_DisassociateCurrentThreadFromCallback(PTP_CALLBACK_INSTANCE pci); 261 262#define SetEventWhenCallbackReturns winpr_SetEventWhenCallbackReturns 263#define ReleaseSemaphoreWhenCallbackReturns winpr_ReleaseSemaphoreWhenCallbackReturns 264#define ReleaseMutexWhenCallbackReturns winpr_ReleaseMutexWhenCallbackReturns 265#define LeaveCriticalSectionWhenCallbackReturns winpr_LeaveCriticalSectionWhenCallbackReturns 266#define FreeLibraryWhenCallbackReturns winpr_FreeLibraryWhenCallbackReturns 267#define DisassociateCurrentThreadFromCallback winpr_DisassociateCurrentThreadFromCallback 268 269#endif 270 271#ifdef __cplusplus 272} 273#endif 274 275#endif /* WINPR_POOL_H */