20#include <winpr/config.h>
22#include <winpr/winpr.h>
24#include <winpr/pool.h>
25#include <winpr/library.h>
29#ifdef WINPR_THREAD_POOL
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);
39static BOOL CALLBACK init_module(
PINIT_ONCE once, PVOID param, PVOID* context)
41 HMODULE kernel32 = LoadLibraryA(
"kernel32.dll");
45 pCreateThreadpoolCleanupGroup =
46 GetProcAddressAs(kernel32,
"CreateThreadpoolCleanupGroup",
void*);
47 pCloseThreadpoolCleanupGroupMembers =
48 GetProcAddressAs(kernel32,
"CloseThreadpoolCleanupGroupMembers",
void*);
49 pCloseThreadpoolCleanupGroup =
50 GetProcAddressAs(kernel32,
"CloseThreadpoolCleanupGroup",
void*);
57PTP_CLEANUP_GROUP winpr_CreateThreadpoolCleanupGroup(
void)
59 PTP_CLEANUP_GROUP cleanupGroup =
nullptr;
61 if (!InitOnceExecuteOnce(&init_once_module, init_module,
nullptr,
nullptr))
64 if (pCreateThreadpoolCleanupGroup)
65 return pCreateThreadpoolCleanupGroup();
69 cleanupGroup = (PTP_CLEANUP_GROUP)calloc(1,
sizeof(TP_CLEANUP_GROUP));
74 cleanupGroup->groups = ArrayList_New(FALSE);
76 if (!cleanupGroup->groups)
87 PTP_CLEANUP_GROUP_CANCEL_CALLBACK pfng)
89 pcbe->CleanupGroup = ptpcg;
90 pcbe->CleanupGroupCancelCallback = pfng;
92 pcbe->CleanupGroup->env = pcbe;
96VOID winpr_CloseThreadpoolCleanupGroupMembers(WINPR_ATTR_UNUSED PTP_CLEANUP_GROUP ptpcg,
97 WINPR_ATTR_UNUSED BOOL fCancelPendingCallbacks,
98 WINPR_ATTR_UNUSED PVOID pvCleanupContext)
101 if (!InitOnceExecuteOnce(&init_once_module, init_module,
nullptr,
nullptr))
104 if (pCloseThreadpoolCleanupGroupMembers)
106 pCloseThreadpoolCleanupGroupMembers(ptpcg, fCancelPendingCallbacks, pvCleanupContext);
112 while (ArrayList_Count(ptpcg->groups) > 0)
114 PTP_WORK work = ArrayList_GetItem(ptpcg->groups, 0);
115 winpr_CloseThreadpoolWork(work);
121VOID winpr_CloseThreadpoolCleanupGroup(PTP_CLEANUP_GROUP ptpcg)
124 if (!InitOnceExecuteOnce(&init_once_module, init_module,
nullptr,
nullptr))
127 if (pCloseThreadpoolCleanupGroup)
129 pCloseThreadpoolCleanupGroup(ptpcg);
135 if (ptpcg && ptpcg->groups)
136 ArrayList_Free(ptpcg->groups);
138 if (ptpcg && ptpcg->env)
139 ptpcg->env->CleanupGroup =
nullptr;