FreeRDP
include/winpr/pool.h
1 
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 
31 typedef DWORD TP_VERSION, *PTP_VERSION;
32 
33 typedef struct S_TP_CALLBACK_INSTANCE TP_CALLBACK_INSTANCE, *PTP_CALLBACK_INSTANCE;
34 
35 typedef VOID (*PTP_SIMPLE_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context);
36 
37 typedef struct S_TP_POOL TP_POOL, *PTP_POOL;
38 
39 typedef struct
40 {
41  size_t StackReserve;
42  size_t StackCommit;
44 
45 typedef struct S_TP_CLEANUP_GROUP TP_CLEANUP_GROUP, *PTP_CLEANUP_GROUP;
46 
47 typedef VOID (*PTP_CLEANUP_GROUP_CANCEL_CALLBACK)(PVOID ObjectContext, PVOID CleanupContext);
48 
49 typedef struct
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  PTP_SIMPLE_CALLBACK FinalizationCallback;
57 
58  union
59  {
60  DWORD Flags;
61  struct
62  {
63  DWORD LongFunction : 1;
64  DWORD Persistent : 1;
65  DWORD Private : 30;
66  } s;
67  } u;
69 
71 
72 typedef struct S_TP_WORK TP_WORK, *PTP_WORK;
73 typedef struct S_TP_TIMER TP_TIMER, *PTP_TIMER;
74 
75 typedef DWORD TP_WAIT_RESULT;
76 typedef struct S_TP_WAIT TP_WAIT, *PTP_WAIT;
77 
78 typedef struct S_TP_IO TP_IO, *PTP_IO;
79 
80 typedef VOID (*PTP_WORK_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK Work);
81 typedef VOID (*PTP_TIMER_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_TIMER Timer);
82 typedef VOID (*PTP_WAIT_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WAIT Wait,
83  TP_WAIT_RESULT WaitResult);
84 
85 #endif /* _WIN32 not defined */
86 
87 /*
88 There is a bug in the Win8 header that defines the IO
89 callback unconditionally. Versions of Windows greater
90 than XP will conditionally define it. The following
91 logic tries to fix that.
92 */
93 #ifdef _THREADPOOLAPISET_H_
94 #define PTP_WIN32_IO_CALLBACK_DEFINED 1
95 #else
96 #if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
97 #define PTP_WIN32_IO_CALLBACK_DEFINED 1
98 #endif
99 #endif
100 
101 #ifndef PTP_WIN32_IO_CALLBACK_DEFINED
102 
103 typedef VOID (*PTP_WIN32_IO_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context,
104  PVOID Overlapped, ULONG IoResult,
105  ULONG_PTR NumberOfBytesTransferred, PTP_IO Io);
106 
107 #endif
108 
109 #if !defined(_WIN32)
110 #define WINPR_THREAD_POOL 1
111 #elif defined(_WIN32) && (_WIN32_WINNT < 0x0600)
112 #define WINPR_THREAD_POOL 1
113 #elif defined(__MINGW32__) && (__MINGW64_VERSION_MAJOR < 7)
114 #define WINPR_THREAD_POOL 1
115 #endif
116 
117 #ifdef __cplusplus
118 extern "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 */
214 
215  WINPR_API BOOL winpr_CallbackMayRunLong(PTP_CALLBACK_INSTANCE pci);
216 
217  /* Callback Clean-up */
218 
219  WINPR_API VOID winpr_SetEventWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE evt);
220  WINPR_API VOID winpr_ReleaseSemaphoreWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE sem,
221  DWORD crel);
222  WINPR_API VOID winpr_ReleaseMutexWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE mut);
223  WINPR_API VOID winpr_LeaveCriticalSectionWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci,
224  PCRITICAL_SECTION pcs);
225  WINPR_API VOID winpr_FreeLibraryWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HMODULE mod);
226  WINPR_API VOID winpr_DisassociateCurrentThreadFromCallback(PTP_CALLBACK_INSTANCE pci);
227 
228 #define SetEventWhenCallbackReturns winpr_SetEventWhenCallbackReturns
229 #define ReleaseSemaphoreWhenCallbackReturns winpr_ReleaseSemaphoreWhenCallbackReturns
230 #define ReleaseMutexWhenCallbackReturns winpr_ReleaseMutexWhenCallbackReturns
231 #define LeaveCriticalSectionWhenCallbackReturns winpr_LeaveCriticalSectionWhenCallbackReturns
232 #define FreeLibraryWhenCallbackReturns winpr_FreeLibraryWhenCallbackReturns
233 #define DisassociateCurrentThreadFromCallback winpr_DisassociateCurrentThreadFromCallback
234 
235 #endif /* WINPR_THREAD_POOL */
236 
237 #if !defined(_WIN32)
238 #define WINPR_CALLBACK_ENVIRON 1
239 #elif defined(_WIN32) && (_WIN32_WINNT < 0x0600)
240 #define WINPR_CALLBACK_ENVIRON 1
241 #elif defined(__MINGW32__) && (__MINGW64_VERSION_MAJOR < 9)
242 #define WINPR_CALLBACK_ENVIRON 1
243 #endif
244 
245 #ifdef WINPR_CALLBACK_ENVIRON
246  /* some version of mingw are missing Callback Environment functions */
247 
248  /* Callback Environment */
249 
250  static INLINE VOID InitializeThreadpoolEnvironment(PTP_CALLBACK_ENVIRON pcbe)
251  {
252  const TP_CALLBACK_ENVIRON empty = { 0 };
253  *pcbe = empty;
254  pcbe->Version = 1;
255  }
256 
257  static INLINE VOID DestroyThreadpoolEnvironment(PTP_CALLBACK_ENVIRON pcbe)
258  {
259  /* no actions, this may change in a future release. */
260  }
261 
262  static INLINE VOID SetThreadpoolCallbackPool(PTP_CALLBACK_ENVIRON pcbe, PTP_POOL ptpp)
263  {
264  pcbe->Pool = ptpp;
265  }
266 
267  static INLINE VOID SetThreadpoolCallbackRunsLong(PTP_CALLBACK_ENVIRON pcbe)
268  {
269  pcbe->u.s.LongFunction = 1;
270  }
271 
272  static INLINE VOID SetThreadpoolCallbackLibrary(PTP_CALLBACK_ENVIRON pcbe, PVOID mod)
273  {
274  pcbe->RaceDll = mod;
275  }
276 #endif
277 
278 #ifdef __cplusplus
279 }
280 #endif
281 
282 #endif /* WINPR_POOL_H */