FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
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 = NULL;
60#ifdef _WIN32
61 InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL);
62
63 if (pCreateThreadpoolCleanupGroup)
64 return pCreateThreadpoolCleanupGroup();
65
66 return cleanupGroup;
67#else
68 cleanupGroup = (PTP_CLEANUP_GROUP)calloc(1, sizeof(TP_CLEANUP_GROUP));
69
70 if (!cleanupGroup)
71 return NULL;
72
73 cleanupGroup->groups = ArrayList_New(FALSE);
74
75 if (!cleanupGroup->groups)
76 {
77 free(cleanupGroup);
78 return NULL;
79 }
80
81 return cleanupGroup;
82#endif
83}
84
85VOID winpr_SetThreadpoolCallbackCleanupGroup(PTP_CALLBACK_ENVIRON pcbe, PTP_CLEANUP_GROUP ptpcg,
86 PTP_CLEANUP_GROUP_CANCEL_CALLBACK pfng)
87{
88 pcbe->CleanupGroup = ptpcg;
89 pcbe->CleanupGroupCancelCallback = pfng;
90#ifndef _WIN32
91 pcbe->CleanupGroup->env = pcbe;
92#endif
93}
94
95VOID winpr_CloseThreadpoolCleanupGroupMembers(WINPR_ATTR_UNUSED PTP_CLEANUP_GROUP ptpcg,
96 WINPR_ATTR_UNUSED BOOL fCancelPendingCallbacks,
97 WINPR_ATTR_UNUSED PVOID pvCleanupContext)
98{
99#ifdef _WIN32
100 InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL);
101
102 if (pCloseThreadpoolCleanupGroupMembers)
103 {
104 pCloseThreadpoolCleanupGroupMembers(ptpcg, fCancelPendingCallbacks, pvCleanupContext);
105 return;
106 }
107
108#else
109
110 while (ArrayList_Count(ptpcg->groups) > 0)
111 {
112 PTP_WORK work = ArrayList_GetItem(ptpcg->groups, 0);
113 winpr_CloseThreadpoolWork(work);
114 }
115
116#endif
117}
118
119VOID winpr_CloseThreadpoolCleanupGroup(PTP_CLEANUP_GROUP ptpcg)
120{
121#ifdef _WIN32
122 InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL);
123
124 if (pCloseThreadpoolCleanupGroup)
125 {
126 pCloseThreadpoolCleanupGroup(ptpcg);
127 return;
128 }
129
130#else
131
132 if (ptpcg && ptpcg->groups)
133 ArrayList_Free(ptpcg->groups);
134
135 if (ptpcg && ptpcg->env)
136 ptpcg->env->CleanupGroup = NULL;
137
138 free(ptpcg);
139#endif
140}
141
142#endif /* WINPR_THREAD_POOL defined */