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 = NULL;
61 InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL);
63 if (pCreateThreadpoolCleanupGroup)
64 return pCreateThreadpoolCleanupGroup();
68 cleanupGroup = (PTP_CLEANUP_GROUP)calloc(1,
sizeof(TP_CLEANUP_GROUP));
73 cleanupGroup->groups = ArrayList_New(FALSE);
75 if (!cleanupGroup->groups)
86 PTP_CLEANUP_GROUP_CANCEL_CALLBACK pfng)
88 pcbe->CleanupGroup = ptpcg;
89 pcbe->CleanupGroupCancelCallback = pfng;
91 pcbe->CleanupGroup->env = pcbe;
95VOID winpr_CloseThreadpoolCleanupGroupMembers(WINPR_ATTR_UNUSED PTP_CLEANUP_GROUP ptpcg,
96 WINPR_ATTR_UNUSED BOOL fCancelPendingCallbacks,
97 WINPR_ATTR_UNUSED PVOID pvCleanupContext)
100 InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL);
102 if (pCloseThreadpoolCleanupGroupMembers)
104 pCloseThreadpoolCleanupGroupMembers(ptpcg, fCancelPendingCallbacks, pvCleanupContext);
110 while (ArrayList_Count(ptpcg->groups) > 0)
112 PTP_WORK work = ArrayList_GetItem(ptpcg->groups, 0);
113 winpr_CloseThreadpoolWork(work);
119VOID winpr_CloseThreadpoolCleanupGroup(PTP_CLEANUP_GROUP ptpcg)
122 InitOnceExecuteOnce(&init_once_module, init_module, NULL, NULL);
124 if (pCloseThreadpoolCleanupGroup)
126 pCloseThreadpoolCleanupGroup(ptpcg);
132 if (ptpcg && ptpcg->groups)
133 ArrayList_Free(ptpcg->groups);
135 if (ptpcg && ptpcg->env)
136 ptpcg->env->CleanupGroup = NULL;