CWaitableTimer

The Microsoft. Win32. API provides 4 functions for dealing with waitable timer objects, providing very high resolution (100 nSec.) timer capabilities for applications.

The CWaitableTimer is a wrapper class for the Microsoft. Win32. API waitable timer objects. The class is intended to be extended and accessed by derivative classes.

The class constructor establishes the timer and default properties. There are numerous methods for setting and accessing the timer's properties and 2 methods used for starting and stopping the timer.

This class does not directly implement the callback function features. If it is desired, this functionality should be added in the derivative class. The base class sets a waitable timer event and waits for the event to be reset via a wait complete or reset of the timer.

The CWaitableTimer class can be extended (sub-classed) to provide access to specific structures and values, and to enhace its capabilities. Refer to the Microsoft Platform SDK: DLLs, Processes, and Threads documentation from the MSDN (support.microsoft.com).

CWaitableTimer contains the following methods, more completely documented in the download file:

  • CWaitableTimer(CString p_TimerName, bool p_Periodic, LONG p_Period);
    
    p_TimerName is a string specifying the name of the timer object. The name is limited to MAX_PATH characters, and is case sensitive. If the string specified in p_TimerName matches the name of an existing named timer object, an OpenWaitableTimer operation is performed to connect the new CWaitableTimer object to the existing timer object. If p_TimerName is not specified, or no match to an existing timer object is found, a CreateWaitableTimer operation is performed to create a new timer object.

    p_Periodic is set to true to create a periodic timer, set to false to create a manual reset timer.

    p_Period is the timer period in mSec.

    Remarks
    CWaitableTimer establishes the timer object and default properties. The timer HANDLE is allocated but the timer is not started (refer to Start).

  • bool Start(void);
    

    Remarks
    Start activates the waitable timer using the current values. When the due time arrives, the timer is signaled.

  • bool Stop(void);
    
    Remarks
    The timer is stopped. The timer handle and settings remain in tact.
  • void Period(LONG p_Period);
    

    p_Period - the period (timeout value) of the counter, in mSec.

    Remarks
    Specifies the period of the timer, in milliseconds. If p_Period is zero, the timer is signaled once. If p_Period is greater than zero, the timer is periodic (automatically reactivates each time the period elapses, until the timer is canceled).

  • void Expires(__int64 p_Expires);
    void Expires(__int64 p_Expires, bool p_Relative, int p_BaseTime);
    

    p_Expires is the timer expiration count. Specifies when the state of the timer is to be set to signaled, in 100 nanosecond intervals. The format is the FILETIME structure, a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601.

    Set p_Relative true to indicate a count relative to the current system time, false to indicates an absolute (UTC) FILETIME.

    For relative timers, p_BaseTime specifies the format of the value in p_Expires.

    Remarks
    Set the timer expiration count. Form 1 sets the timer expiration count in 100 nSec increments (64-bits). Form 2 allows specification of a base time to apply to the value in p_Expires, signifying (100) nanoseconds, microseconds, milliseconds, seconds, minutes or hours.

  • HANDLE TimerHandle(void);
    

    Remarks
    Returns a handle to the timer.

  • bool Valid(void);
    

    Remarks
    Returns the setting of the global flag g_valid. g_valid is true if the timer has been initialized. It is false if the timer has not been initialized, or a fatal error has occurred.

  • DWORD Error(void);
    

    Remarks
    Returns the value of the last error recorded.

  • int Result(void);
    

    Remarks
    Return the value in the result field. This field contains a value indicating the result of the last operation.

Installing and Using the Class

To use this class,
  1. Copy CWaitableTimer.cpp and CWaitableTimer.h to the same directory as your project or class libraries;
  2. Include CWaitableTimer.cpp and CWaitableTimer.h in your project;
  3. Add CWaitableTimer.h to any modules which make reference to CWaitableTimer or one of its' methods or variables. This will normally take the form of
      #include "CWaitableTimer.h"
    in the header files in which the CWaitableTimer object is declared;
  4. Create and initialize a timer object;

  5. Start the timer;

  6. Process timer events and wait for the timer to expire. Waitable timers can be used with any of the four types of wait functions: single-object, multiple-object, alertable or registered; and

  7. Stop the timer and release the timer object.

Creating a Single Event, Manual Reset Timer

This example shows one way to create a single shot (manual reset) 5 second timer object. This example will use the WaitForSingleObject function to synchronize with the timer:

int l_TimeValue = 5 * 1000;  // 5000 mSec = 5 sec
CWaitableTimer * g_pTimer;

//////////////////////////////////////////////////////
//
//		Attempt to get a timer object
//
//////////////////////////////////////////////////////
g_pTimer = new CWaitableTimer("MyTimer",    // Timer name
false,        // true = periodic
l_TimeValue); // 5 seconds
if (! g_pTimer->Valid())
{
//
//    Unable to get a timer handle.
//    Handle error and delete the timer object
//
delete g_pTimer;
}

//////////////////////////////////////////////////////
//
//         Start timer, if possible
//
//////////////////////////////////////////////////////
if (! g_pTimer->Start())
{
//
//        Unable to start Timer
//        Handle error and delete the timer object
//
delete g_pTimer;
}

//////////////////////////////////////////////////////
//
//    Wait for timer interrupt(s)
//
//////////////////////////////////////////////////////
while (true)
{
if (WaitForSingleObject(g_pTimer->TimerHandle(), 
2 * l_TimeValue) != WAIT_OBJECT_0)
{
//
//    Timer didn't respond in the required time
//    Handle error and delete the timer object
//
break;
}
//
//    Process timer interrupt
//
//    For a single shot (Manual reset)
//    timer, exit the loop
//
break;
}

//////////////////////////////////////////////////////
//
//        Stop timer, if possible
//
//////////////////////////////////////////////////////
g_pTimer->Stop();

delete g_pTimer;

Sample Application

A VisualC++ 6 workspace containing a sample project is included with the CWaitableTimer download:

    ElapsedTimer
    A Windows console program which demonstrates single and multiple event timers.

Downloads

Download CWaitableTimer class - 39 Kb
Download demo projects - 91 Kb


Comments

  • But

    Posted by Legacy on 08/15/2002 12:00am

    Originally posted by: Sank

    So you get all this supposed accuracy, but if you read the fine print, it says "The actual timer accuracy depends on the capability of your hardware."

    As it turns out, on my machine this method is no more accurate than using WM_TIMER messages, or making a call to Sleep(milliseconds).

    I think they all are based on the same underlying speed of Windows' multi-tasking mechanism, which would explain their identical performance.

    It seems the best I can do is with timeSetEvent. It is very accurate, since it is, I think, interrupt driven? But it has limitations of only 16 timers, and there seem to be some undocumented bugs that cause assert errors and other crap in my application. I have to work on that.

    There is another article on CodeGuru that has to do with timeSetEvent.

    It appears that I may not be able to do what I need to do with the accuracy I need to do it. I just wanted to rant somewhere.

    If someone has a solution, feel free to let me know: sank at spu dot edu

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • In this webinar, IDC featured speaker Steve Conway, Vice President of High Performance Computing, will present an update on the global x86 HPC cluster market. The presentation will include IDC's five-year forecast for the medium- to large-scale technical computing and data analysis emerging markets by systems, processors and application middleware. Cray's featured speaker, John Lee, Vice President of Cray Cluster Advanced Technology Systems, will present the new Cray® CS400™ cluster series based on …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds