Monday, November 22, 2010

WaitableTimer in C++

This is an example code for calling a waitable timer. This is a good way to wait for a timer event without using CPU (thread blocks). There is a small trick in the code. It’s hard to create a FILETIME properly so I create a SYSTEMTIME (and set it according to my needs), convert it to FILETIME, finally I cast that to LARGE_INTEGER* (to fulfill the needs of SetWaitableTimer).

I set the timer to autoreset, so it will restart counting after firing the event (counts again and again). The first event (“CALLED”) occurs after 3 secs, the subsequent events occur after 2 secs.

The WaitForSingleObject blocks until a timer event is fired. I break the loop after 5 events, stop the timer and delete the timer handle.

stdafx.h

#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <Windows.h>

using namespace std;

WaitableTimer.cpp

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
int count = 0; // Iteration counter

HANDLE hTimer = NULL; // WaitableTimer handle
hTimer = CreateWaitableTimer( // Create waitable timer
NULL,
FALSE, // Autoreset --> timer restarts counting after event fired
NULL);

SYSTEMTIME time; // System time structure
GetSystemTime(&time); // Curren time
time.wSecond += 3; // Wait 3 sec

FILETIME ftime; // File time (expected by SetWaitableTimer)
SystemTimeToFileTime(&time, &ftime); // Convert system to file time


if(!SetWaitableTimer( // Set waitable timer
hTimer, // Timer handle
reinterpret_cast<LARGE_INTEGER*>(&ftime), // Convert file time to large integer
2000, // Period time, fire again after 2 sec
NULL,
NULL,
0))
{
cout << "SetWaitableTimer failed" << GetLastError() << endl;
};


while(WaitForSingleObject(hTimer, 5000) == WAIT_OBJECT_0){ // Wait for timer event
cout << "CALLED " << ++count << endl;
if(count+1 > 5){ // Exit after 5 events
break;
}
}

CancelWaitableTimer(hTimer); // Stop timer
CloseHandle(hTimer); // Delete handle

return 0;
}

See source code: http://code.google.com/p/artur02/source/browse/trunk/CPP/WaitableTimer/WaitableTimer.cpp

Waitable timer objects: http://msdn.microsoft.com/en-us/library/ms687012(VS.85).aspx
CreateWaitableTimer function: http://msdn.microsoft.com/en-us/library/ms682492(v=VS.85).aspx
SetWaitableTimer function: http://msdn.microsoft.com/en-us/library/ms686289(v=VS.85).aspx
Systemtime structure: http://msdn.microsoft.com/en-us/library/ms687008(v=VS.85).aspx
Usage example: http://msdn.microsoft.com/en-us/library/ms687008(v=VS.85).aspx