19#include <winpr/wtypes.h>
20#include <winpr/thread.h>
21#include <winpr/synch.h>
29static void CALLBACK userApc(ULONG_PTR arg)
31 UserApcArg* userArg = (UserApcArg*)arg;
32 userArg->called = TRUE;
35static DWORD WINAPI uncleanThread(LPVOID lpThreadParameter)
38 UserApcArg* userArg = (UserApcArg*)lpThreadParameter;
39 if (!QueueUserAPC((PAPCFUNC)userApc, _GetCurrentThread(), (ULONG_PTR)lpThreadParameter))
41 userArg->error = TRUE;
48static DWORD WINAPI cleanThread(LPVOID lpThreadParameter)
65static VOID CALLBACK Timer1APCProc(LPVOID lpArg, DWORD dwTimerLowValue, DWORD dwTimerHighValue)
67 UncleanCloseData* data = (UncleanCloseData*)lpArg;
69 (void)CloseHandle(data->timer2);
73static VOID CALLBACK Timer2APCProc(LPVOID lpArg, DWORD dwTimerLowValue, DWORD dwTimerHighValue)
75 UncleanCloseData* data = (UncleanCloseData*)lpArg;
79static DWORD closeHandleTest(LPVOID lpThreadParameter)
82 UncleanCloseData* data = (UncleanCloseData*)lpThreadParameter;
83 data->endTest = FALSE;
85 dueTime.QuadPart = -500;
86 if (!SetWaitableTimer(data->timer1, &dueTime, 0, Timer1APCProc, lpThreadParameter, FALSE))
89 dueTime.QuadPart = -900;
90 if (!SetWaitableTimer(data->timer2, &dueTime, 0, Timer2APCProc, lpThreadParameter, FALSE))
93 while (!data->endTest)
100int TestSynchAPC(
int argc,
char* argv[])
102 HANDLE thread = NULL;
103 UserApcArg userApcArg;
105 userApcArg.error = FALSE;
106 userApcArg.called = FALSE;
112 if (!QueueUserAPC((PAPCFUNC)userApc, _GetCurrentThread(), (ULONG_PTR)&userApcArg))
115 if (SleepEx(100, FALSE) != 0)
118 if (SleepEx(100, TRUE) != WAIT_IO_COMPLETION)
121 if (!userApcArg.called)
124 userApcArg.called = FALSE;
127 thread = CreateThread(NULL, 0, uncleanThread, &userApcArg, 0, NULL);
130 (void)WaitForSingleObject(thread, INFINITE);
131 (void)CloseHandle(thread);
133 if (userApcArg.called || userApcArg.error)
137 thread = CreateThread(NULL, 0, cleanThread, &userApcArg, 0, NULL);
141 if (!QueueUserAPC((PAPCFUNC)userApc, thread, (ULONG_PTR)&userApcArg))
144 (void)WaitForSingleObject(thread, INFINITE);
145 (void)CloseHandle(thread);
147 if (!userApcArg.called)