Milestone 5: deliver embedded RDP sessions and lifecycle hardening
This commit is contained in:
92
third_party/FreeRDP/winpr/libwinpr/synch/test/TestSynchWaitableTimerAPC.c
vendored
Normal file
92
third_party/FreeRDP/winpr/libwinpr/synch/test/TestSynchWaitableTimerAPC.c
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/sysinfo.h>
|
||||
|
||||
static int g_Count = 0;
|
||||
static HANDLE g_Event = nullptr;
|
||||
|
||||
struct apc_data
|
||||
{
|
||||
UINT32 StartTime;
|
||||
};
|
||||
typedef struct apc_data APC_DATA;
|
||||
|
||||
static VOID CALLBACK TimerAPCProc(LPVOID lpArg, DWORD dwTimerLowValue, DWORD dwTimerHighValue)
|
||||
{
|
||||
APC_DATA* apcData = nullptr;
|
||||
UINT32 CurrentTime = GetTickCount();
|
||||
WINPR_UNUSED(dwTimerLowValue);
|
||||
WINPR_UNUSED(dwTimerHighValue);
|
||||
|
||||
if (!lpArg)
|
||||
return;
|
||||
|
||||
apcData = (APC_DATA*)lpArg;
|
||||
printf("TimerAPCProc: time: %" PRIu32 "\n", CurrentTime - apcData->StartTime);
|
||||
g_Count++;
|
||||
|
||||
if (g_Count >= 5)
|
||||
{
|
||||
(void)SetEvent(g_Event);
|
||||
}
|
||||
}
|
||||
|
||||
int TestSynchWaitableTimerAPC(int argc, char* argv[])
|
||||
{
|
||||
int status = -1;
|
||||
DWORD rc = 0;
|
||||
HANDLE hTimer = nullptr;
|
||||
BOOL bSuccess = 0;
|
||||
LARGE_INTEGER due = WINPR_C_ARRAY_INIT;
|
||||
APC_DATA apcData = WINPR_C_ARRAY_INIT;
|
||||
WINPR_UNUSED(argc);
|
||||
WINPR_UNUSED(argv);
|
||||
g_Event = CreateEvent(nullptr, TRUE, FALSE, nullptr);
|
||||
|
||||
if (!g_Event)
|
||||
{
|
||||
printf("Failed to create event\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
hTimer = CreateWaitableTimer(nullptr, FALSE, nullptr);
|
||||
if (!hTimer)
|
||||
goto cleanup;
|
||||
|
||||
due.QuadPart = -1000 * 100LL; /* 0.1 seconds */
|
||||
apcData.StartTime = GetTickCount();
|
||||
bSuccess = SetWaitableTimer(hTimer, &due, 10, TimerAPCProc, &apcData, FALSE);
|
||||
|
||||
if (!bSuccess)
|
||||
goto cleanup;
|
||||
|
||||
/* nothing shall happen after 0.12 second, because thread is not in alertable state */
|
||||
rc = WaitForSingleObject(g_Event, 120);
|
||||
if (rc != WAIT_TIMEOUT)
|
||||
goto cleanup;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
rc = WaitForSingleObjectEx(g_Event, INFINITE, TRUE);
|
||||
if (rc == WAIT_OBJECT_0)
|
||||
break;
|
||||
|
||||
if (rc == WAIT_IO_COMPLETION)
|
||||
continue;
|
||||
|
||||
printf("Failed to wait for completion event (%" PRIu32 ")\n", GetLastError());
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = 0;
|
||||
cleanup:
|
||||
|
||||
if (hTimer)
|
||||
(void)CloseHandle(hTimer);
|
||||
|
||||
if (g_Event)
|
||||
(void)CloseHandle(g_Event);
|
||||
|
||||
return status;
|
||||
}
|
||||
Reference in New Issue
Block a user