Coverage Report

Created: 2026-04-12 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/FreeRDP/winpr/include/winpr/pool.h
Line
Count
Source
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
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;
43
} TP_POOL_STACK_INFORMATION, *PTP_POOL_STACK_INFORMATION;
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;
68
} TP_CALLBACK_ENVIRON_V1;
69
70
typedef TP_CALLBACK_ENVIRON_V1 TP_CALLBACK_ENVIRON, *PTP_CALLBACK_ENVIRON;
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_ATTR_NODISCARD
127
  WINPR_API PTP_WAIT winpr_CreateThreadpoolWait(PTP_WAIT_CALLBACK pfnwa, PVOID pv,
128
                                                PTP_CALLBACK_ENVIRON pcbe);
129
  WINPR_API VOID winpr_CloseThreadpoolWait(PTP_WAIT pwa);
130
  WINPR_API VOID winpr_SetThreadpoolWait(PTP_WAIT pwa, HANDLE h, PFILETIME pftTimeout);
131
  WINPR_API VOID winpr_WaitForThreadpoolWaitCallbacks(PTP_WAIT pwa, BOOL fCancelPendingCallbacks);
132
133
#define CreateThreadpoolWait winpr_CreateThreadpoolWait
134
#define CloseThreadpoolWait winpr_CloseThreadpoolWait
135
#define SetThreadpoolWait winpr_SetThreadpoolWait
136
#define WaitForThreadpoolWaitCallbacks winpr_WaitForThreadpoolWaitCallbacks
137
138
  /* Work */
139
140
  WINPR_ATTR_NODISCARD
141
  WINPR_API PTP_WORK winpr_CreateThreadpoolWork(PTP_WORK_CALLBACK pfnwk, PVOID pv,
142
                                                PTP_CALLBACK_ENVIRON pcbe);
143
144
  WINPR_API VOID winpr_CloseThreadpoolWork(PTP_WORK pwk);
145
  WINPR_API VOID winpr_SubmitThreadpoolWork(PTP_WORK pwk);
146
147
  WINPR_ATTR_NODISCARD
148
  WINPR_API BOOL winpr_TrySubmitThreadpoolCallback(PTP_SIMPLE_CALLBACK pfns, PVOID pv,
149
                                                   PTP_CALLBACK_ENVIRON pcbe);
150
151
  WINPR_API VOID winpr_WaitForThreadpoolWorkCallbacks(PTP_WORK pwk, BOOL fCancelPendingCallbacks);
152
153
0
#define CreateThreadpoolWork winpr_CreateThreadpoolWork
154
0
#define CloseThreadpoolWork winpr_CloseThreadpoolWork
155
0
#define SubmitThreadpoolWork winpr_SubmitThreadpoolWork
156
#define TrySubmitThreadpoolCallback winpr_TrySubmitThreadpoolCallback
157
0
#define WaitForThreadpoolWorkCallbacks winpr_WaitForThreadpoolWorkCallbacks
158
159
  /* Timer */
160
161
  WINPR_ATTR_NODISCARD
162
  WINPR_API PTP_TIMER winpr_CreateThreadpoolTimer(PTP_TIMER_CALLBACK pfnti, PVOID pv,
163
                                                  PTP_CALLBACK_ENVIRON pcbe);
164
  WINPR_API VOID winpr_CloseThreadpoolTimer(PTP_TIMER pti);
165
166
  WINPR_ATTR_NODISCARD
167
  WINPR_API BOOL winpr_IsThreadpoolTimerSet(PTP_TIMER pti);
168
169
  WINPR_API VOID winpr_SetThreadpoolTimer(PTP_TIMER pti, PFILETIME pftDueTime, DWORD msPeriod,
170
                                          DWORD msWindowLength);
171
  WINPR_API VOID winpr_WaitForThreadpoolTimerCallbacks(PTP_TIMER pti,
172
                                                       BOOL fCancelPendingCallbacks);
173
174
#define CreateThreadpoolTimer winpr_CreateThreadpoolTimer
175
#define CloseThreadpoolTimer winpr_CloseThreadpoolTimer
176
#define IsThreadpoolTimerSet winpr_IsThreadpoolTimerSet
177
#define SetThreadpoolTimer winpr_SetThreadpoolTimer
178
#define WaitForThreadpoolTimerCallbacks winpr_WaitForThreadpoolTimerCallbacks
179
180
  /* I/O */
181
182
  WINPR_ATTR_NODISCARD
183
  WINPR_API PTP_IO winpr_CreateThreadpoolIo(HANDLE fl, PTP_WIN32_IO_CALLBACK pfnio, PVOID pv,
184
                                            PTP_CALLBACK_ENVIRON pcbe);
185
186
  WINPR_API VOID winpr_CloseThreadpoolIo(PTP_IO pio);
187
  WINPR_API VOID winpr_StartThreadpoolIo(PTP_IO pio);
188
  WINPR_API VOID winpr_CancelThreadpoolIo(PTP_IO pio);
189
  WINPR_API VOID winpr_WaitForThreadpoolIoCallbacks(PTP_IO pio, BOOL fCancelPendingCallbacks);
190
191
#define CreateThreadpoolIo winpr_CreateThreadpoolIo
192
#define CloseThreadpoolIo winpr_CloseThreadpoolIo
193
#define StartThreadpoolIo winpr_StartThreadpoolIo
194
#define CancelThreadpoolIo winpr_CancelThreadpoolIo
195
#define WaitForThreadpoolIoCallbacks winpr_WaitForThreadpoolIoCallbacks
196
197
  /* Clean-up Group */
198
199
  WINPR_API VOID winpr_SetThreadpoolCallbackCleanupGroup(PTP_CALLBACK_ENVIRON pcbe,
200
                                                         PTP_CLEANUP_GROUP ptpcg,
201
                                                         PTP_CLEANUP_GROUP_CANCEL_CALLBACK pfng);
202
203
  WINPR_ATTR_NODISCARD
204
  WINPR_API PTP_CLEANUP_GROUP winpr_CreateThreadpoolCleanupGroup(void);
205
206
  WINPR_API VOID winpr_CloseThreadpoolCleanupGroupMembers(PTP_CLEANUP_GROUP ptpcg,
207
                                                          BOOL fCancelPendingCallbacks,
208
                                                          PVOID pvCleanupContext);
209
  WINPR_API VOID winpr_CloseThreadpoolCleanupGroup(PTP_CLEANUP_GROUP ptpcg);
210
211
#define SetThreadpoolCallbackCleanupGroup winpr_SetThreadpoolCallbackCleanupGroup
212
#define CreateThreadpoolCleanupGroup winpr_CreateThreadpoolCleanupGroup
213
#define CloseThreadpoolCleanupGroupMembers winpr_CloseThreadpoolCleanupGroupMembers
214
#define CloseThreadpoolCleanupGroup winpr_CloseThreadpoolCleanupGroup
215
216
  /* Pool */
217
218
  WINPR_ATTR_NODISCARD
219
  WINPR_API PTP_POOL winpr_CreateThreadpool(PVOID reserved);
220
221
  WINPR_API VOID winpr_CloseThreadpool(PTP_POOL ptpp);
222
223
  WINPR_API BOOL winpr_SetThreadpoolThreadMinimum(PTP_POOL ptpp, DWORD cthrdMic);
224
225
  WINPR_API VOID winpr_SetThreadpoolThreadMaximum(PTP_POOL ptpp, DWORD cthrdMost);
226
227
#define CreateThreadpool winpr_CreateThreadpool
228
#define CloseThreadpool winpr_CloseThreadpool
229
0
#define SetThreadpoolThreadMinimum winpr_SetThreadpoolThreadMinimum
230
0
#define SetThreadpoolThreadMaximum winpr_SetThreadpoolThreadMaximum
231
232
  /* Callback */
233
234
  WINPR_ATTR_NODISCARD
235
  WINPR_API BOOL winpr_CallbackMayRunLong(PTP_CALLBACK_INSTANCE pci);
236
237
  /* Callback Clean-up */
238
239
  WINPR_API VOID winpr_SetEventWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE evt);
240
  WINPR_API VOID winpr_ReleaseSemaphoreWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE sem,
241
                                                           DWORD crel);
242
  WINPR_API VOID winpr_ReleaseMutexWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HANDLE mut);
243
  WINPR_API VOID winpr_LeaveCriticalSectionWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci,
244
                                                               PCRITICAL_SECTION pcs);
245
  WINPR_API VOID winpr_FreeLibraryWhenCallbackReturns(PTP_CALLBACK_INSTANCE pci, HMODULE mod);
246
  WINPR_API VOID winpr_DisassociateCurrentThreadFromCallback(PTP_CALLBACK_INSTANCE pci);
247
248
#define SetEventWhenCallbackReturns winpr_SetEventWhenCallbackReturns
249
#define ReleaseSemaphoreWhenCallbackReturns winpr_ReleaseSemaphoreWhenCallbackReturns
250
#define ReleaseMutexWhenCallbackReturns winpr_ReleaseMutexWhenCallbackReturns
251
#define LeaveCriticalSectionWhenCallbackReturns winpr_LeaveCriticalSectionWhenCallbackReturns
252
#define FreeLibraryWhenCallbackReturns winpr_FreeLibraryWhenCallbackReturns
253
#define DisassociateCurrentThreadFromCallback winpr_DisassociateCurrentThreadFromCallback
254
255
#endif /* WINPR_THREAD_POOL */
256
257
#if !defined(_WIN32)
258
#define WINPR_CALLBACK_ENVIRON 1
259
#elif defined(_WIN32) && (_WIN32_WINNT < 0x0600)
260
#define WINPR_CALLBACK_ENVIRON 1
261
#elif defined(__MINGW32__) && (__MINGW64_VERSION_MAJOR < 9)
262
#define WINPR_CALLBACK_ENVIRON 1
263
#endif
264
265
#ifdef WINPR_CALLBACK_ENVIRON
266
  /* some version of mingw are missing Callback Environment functions */
267
268
  /* Callback Environment */
269
270
  static inline VOID InitializeThreadpoolEnvironment(PTP_CALLBACK_ENVIRON pcbe)
271
0
  {
272
0
    const TP_CALLBACK_ENVIRON empty = WINPR_C_ARRAY_INIT;
273
0
    *pcbe = empty;
274
0
    pcbe->Version = 1;
275
0
  }
Unexecuted instantiation: progressive.c:InitializeThreadpoolEnvironment
Unexecuted instantiation: rfx.c:InitializeThreadpoolEnvironment
Unexecuted instantiation: rfx_sse2.c:InitializeThreadpoolEnvironment
Unexecuted instantiation: rfx_neon.c:InitializeThreadpoolEnvironment
Unexecuted instantiation: rfx_decode.c:InitializeThreadpoolEnvironment
Unexecuted instantiation: rfx_encode.c:InitializeThreadpoolEnvironment
Unexecuted instantiation: work.c:InitializeThreadpoolEnvironment
Unexecuted instantiation: pool.c:InitializeThreadpoolEnvironment
276
277
  static inline VOID DestroyThreadpoolEnvironment(WINPR_ATTR_UNUSED PTP_CALLBACK_ENVIRON pcbe)
278
0
  {
279
0
    /* no actions, this may change in a future release. */
280
0
  }
Unexecuted instantiation: progressive.c:DestroyThreadpoolEnvironment
Unexecuted instantiation: rfx.c:DestroyThreadpoolEnvironment
Unexecuted instantiation: rfx_sse2.c:DestroyThreadpoolEnvironment
Unexecuted instantiation: rfx_neon.c:DestroyThreadpoolEnvironment
Unexecuted instantiation: rfx_decode.c:DestroyThreadpoolEnvironment
Unexecuted instantiation: rfx_encode.c:DestroyThreadpoolEnvironment
Unexecuted instantiation: work.c:DestroyThreadpoolEnvironment
Unexecuted instantiation: pool.c:DestroyThreadpoolEnvironment
281
282
  static inline VOID SetThreadpoolCallbackPool(PTP_CALLBACK_ENVIRON pcbe, PTP_POOL ptpp)
283
0
  {
284
0
    pcbe->Pool = ptpp;
285
0
  }
Unexecuted instantiation: progressive.c:SetThreadpoolCallbackPool
Unexecuted instantiation: rfx.c:SetThreadpoolCallbackPool
Unexecuted instantiation: rfx_sse2.c:SetThreadpoolCallbackPool
Unexecuted instantiation: rfx_neon.c:SetThreadpoolCallbackPool
Unexecuted instantiation: rfx_decode.c:SetThreadpoolCallbackPool
Unexecuted instantiation: rfx_encode.c:SetThreadpoolCallbackPool
Unexecuted instantiation: work.c:SetThreadpoolCallbackPool
Unexecuted instantiation: pool.c:SetThreadpoolCallbackPool
286
287
  static inline VOID SetThreadpoolCallbackRunsLong(PTP_CALLBACK_ENVIRON pcbe)
288
0
  {
289
0
    pcbe->u.s.LongFunction = 1;
290
0
  }
Unexecuted instantiation: progressive.c:SetThreadpoolCallbackRunsLong
Unexecuted instantiation: rfx.c:SetThreadpoolCallbackRunsLong
Unexecuted instantiation: rfx_sse2.c:SetThreadpoolCallbackRunsLong
Unexecuted instantiation: rfx_neon.c:SetThreadpoolCallbackRunsLong
Unexecuted instantiation: rfx_decode.c:SetThreadpoolCallbackRunsLong
Unexecuted instantiation: rfx_encode.c:SetThreadpoolCallbackRunsLong
Unexecuted instantiation: work.c:SetThreadpoolCallbackRunsLong
Unexecuted instantiation: pool.c:SetThreadpoolCallbackRunsLong
291
292
  static inline VOID SetThreadpoolCallbackLibrary(PTP_CALLBACK_ENVIRON pcbe, PVOID mod)
293
0
  {
294
0
    pcbe->RaceDll = mod;
295
0
  }
Unexecuted instantiation: progressive.c:SetThreadpoolCallbackLibrary
Unexecuted instantiation: rfx.c:SetThreadpoolCallbackLibrary
Unexecuted instantiation: rfx_sse2.c:SetThreadpoolCallbackLibrary
Unexecuted instantiation: rfx_neon.c:SetThreadpoolCallbackLibrary
Unexecuted instantiation: rfx_decode.c:SetThreadpoolCallbackLibrary
Unexecuted instantiation: rfx_encode.c:SetThreadpoolCallbackLibrary
Unexecuted instantiation: work.c:SetThreadpoolCallbackLibrary
Unexecuted instantiation: pool.c:SetThreadpoolCallbackLibrary
296
#endif
297
298
#ifdef __cplusplus
299
}
300
#endif
301
302
#endif /* WINPR_POOL_H */