FreeRDP
Loading...
Searching...
No Matches
cleanup_group.c
1
20#include <winpr/config.h>
21
22#include <winpr/winpr.h>
23#include <winpr/crt.h>
24#include <winpr/pool.h>
25#include <winpr/library.h>
26
27#include "pool.h"
28
29#ifdef WINPR_THREAD_POOL
30
31#ifdef _WIN32
32static INIT_ONCE init_once_module = INIT_ONCE_STATIC_INIT;
33static PTP_CLEANUP_GROUP(WINAPI* pCreateThreadpoolCleanupGroup)();
34static VOID(WINAPI* pCloseThreadpoolCleanupGroupMembers)(PTP_CLEANUP_GROUP ptpcg,
35 BOOL fCancelPendingCallbacks,
36 PVOID pvCleanupContext);
37static VOID(WINAPI* pCloseThreadpoolCleanupGroup)(PTP_CLEANUP_GROUP ptpcg);
38
39static BOOL CALLBACK init_module(PINIT_ONCE once, PVOID param, PVOID* context)
40{
41 HMODULE kernel32 = LoadLibraryA("kernel32.dll");
42
43 if (kernel32)
44 {
45 pCreateThreadpoolCleanupGroup =
46 GetProcAddressAs(kernel32, "CreateThreadpoolCleanupGroup", void*);
47 pCloseThreadpoolCleanupGroupMembers =
48 GetProcAddressAs(kernel32, "CloseThreadpoolCleanupGroupMembers", void*);
49 pCloseThreadpoolCleanupGroup =
50 GetProcAddressAs(kernel32, "CloseThreadpoolCleanupGroup", void*);
51 }
52
53 return TRUE;
54}
55#endif
56
57PTP_CLEANUP_GROUP winpr_CreateThreadpoolCleanupGroup(void)
58{
59 PTP_CLEANUP_GROUP cleanupGroup = nullptr;
60#ifdef _WIN32
61 if (!InitOnceExecuteOnce(&init_once_module, init_module, nullptr, nullptr))
62 return nullptr;
63
64 if (pCreateThreadpoolCleanupGroup)
65 return pCreateThreadpoolCleanupGroup();
66
67 return cleanupGroup;
68#else
69 cleanupGroup = (PTP_CLEANUP_GROUP)calloc(1, sizeof(TP_CLEANUP_GROUP));
70
71 if (!cleanupGroup)
72 return nullptr;
73
74 cleanupGroup->groups = ArrayList_New(FALSE);
75
76 if (!cleanupGroup->groups)
77 {
78 free(cleanupGroup);
79 return nullptr;
80 }
81
82 return cleanupGroup;
83#endif
84}
85
86VOID winpr_SetThreadpoolCallbackCleanupGroup(PTP_CALLBACK_ENVIRON pcbe, PTP_CLEANUP_GROUP ptpcg,
87 PTP_CLEANUP_GROUP_CANCEL_CALLBACK pfng)
88{
89 pcbe->CleanupGroup = ptpcg;
90 pcbe->CleanupGroupCancelCallback = pfng;
91#ifndef _WIN32
92 pcbe->CleanupGroup->env = pcbe;
93#endif
94}
95
96VOID winpr_CloseThreadpoolCleanupGroupMembers(WINPR_ATTR_UNUSED PTP_CLEANUP_GROUP ptpcg,
97 WINPR_ATTR_UNUSED BOOL fCancelPendingCallbacks,
98 WINPR_ATTR_UNUSED PVOID pvCleanupContext)
99{
100#ifdef _WIN32
101 if (!InitOnceExecuteOnce(&init_once_module, init_module, nullptr, nullptr))
102 return;
103
104 if (pCloseThreadpoolCleanupGroupMembers)
105 {
106 pCloseThreadpoolCleanupGroupMembers(ptpcg, fCancelPendingCallbacks, pvCleanupContext);
107 return;
108 }
109
110#else
111
112 while (ArrayList_Count(ptpcg->groups) > 0)
113 {
114 PTP_WORK work = ArrayList_GetItem(ptpcg->groups, 0);
115 winpr_CloseThreadpoolWork(work);
116 }
117
118#endif
119}
120
121VOID winpr_CloseThreadpoolCleanupGroup(PTP_CLEANUP_GROUP ptpcg)
122{
123#ifdef _WIN32
124 if (!InitOnceExecuteOnce(&init_once_module, init_module, nullptr, nullptr))
125 return;
126
127 if (pCloseThreadpoolCleanupGroup)
128 {
129 pCloseThreadpoolCleanupGroup(ptpcg);
130 return;
131 }
132
133#else
134
135 if (ptpcg && ptpcg->groups)
136 ArrayList_Free(ptpcg->groups);
137
138 if (ptpcg && ptpcg->env)
139 ptpcg->env->CleanupGroup = nullptr;
140
141 free(ptpcg);
142#endif
143}
144
145#endif /* WINPR_THREAD_POOL defined */