3#include <winpr/sysinfo.h> 
    5#include <winpr/synch.h> 
   18  HANDLE CompletionEvent;
 
   20typedef struct apc_data APC_DATA;
 
   22static VOID CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired)
 
   25  APC_DATA* apcData = NULL;
 
   26  UINT32 expectedTime = 0;
 
   27  UINT32 CurrentTime = GetTickCount();
 
   29  WINPR_UNUSED(TimerOrWaitFired);
 
   34  apcData = (APC_DATA*)lpParam;
 
   36  TimerTime = CurrentTime - apcData->StartTime;
 
   37  expectedTime = apcData->DueTime + (apcData->Period * apcData->FireCount);
 
   41  printf(
"TimerRoutine: TimerId: %" PRIu32 
" FireCount: %" PRIu32 
" ActualTime: %" PRIu32
 
   42         " ExpectedTime: %" PRIu32 
" Discrepancy: %" PRIu32 
"\n",
 
   43         apcData->TimerId, apcData->FireCount, TimerTime, expectedTime, TimerTime - expectedTime);
 
   47  if (apcData->FireCount == apcData->MaxFireCount)
 
   49    (void)SetEvent(apcData->CompletionEvent);
 
   53int TestSynchTimerQueue(
int argc, 
char* argv[])
 
   55  HANDLE hTimerQueue = NULL;
 
   56  HANDLE hTimers[TIMER_COUNT];
 
   57  APC_DATA apcData[TIMER_COUNT];
 
   62  hTimerQueue = CreateTimerQueue();
 
   66    printf(
"CreateTimerQueue failed (%" PRIu32 
")\n", GetLastError());
 
   70  for (DWORD index = 0; index < TIMER_COUNT; index++)
 
   72    apcData[index].TimerId = index;
 
   73    apcData[index].StartTime = GetTickCount();
 
   74    apcData[index].DueTime = (index * 10) + 50;
 
   75    apcData[index].Period = 100;
 
   76    apcData[index].FireCount = 0;
 
   77    apcData[index].MaxFireCount = FIRE_COUNT;
 
   79    if (!(apcData[index].CompletionEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
 
   81      printf(
"Failed to create apcData[%" PRIu32 
"] event (%" PRIu32 
")\n", index,
 
   86    if (!CreateTimerQueueTimer(&hTimers[index], hTimerQueue, TimerRoutine, &apcData[index],
 
   87                               apcData[index].DueTime, apcData[index].Period, 0))
 
   89      printf(
"CreateTimerQueueTimer failed (%" PRIu32 
")\n", GetLastError());
 
   94  for (DWORD index = 0; index < TIMER_COUNT; index++)
 
   96    if (WaitForSingleObject(apcData[index].CompletionEvent, 2000) != WAIT_OBJECT_0)
 
   98      printf(
"Failed to wait for timer queue timer #%" PRIu32 
" (%" PRIu32 
")\n", index,
 
  104  for (DWORD index = 0; index < TIMER_COUNT; index++)
 
  110    if (!DeleteTimerQueueTimer(hTimerQueue, hTimers[index], INVALID_HANDLE_VALUE))
 
  112      printf(
"DeleteTimerQueueTimer failed (%" PRIu32 
")\n", GetLastError());
 
  115    (void)CloseHandle(apcData[index].CompletionEvent);
 
  118  if (!DeleteTimerQueue(hTimerQueue))
 
  120    printf(
"DeleteTimerQueue failed (%" PRIu32 
")\n", GetLastError());