How to Use Timers in Windows - visual-studio

What are the various ways that a timer can be set up using the Windows API. What are the pros and cons of each method?
I'm using MS DevStudio's C++.

There are two timer related functions on the Windows system: SetTimer and KillTimer (I know, the names are odd - CreateTimer and DestroyTimer would be more sensible, as in CreateWindow and DestroyWindow, but that is what is available).
SetTimer can function in one of two modes: the timer event can trigger a user defined callback or it can post a message to a window. The format of this function is:
timer_id = SetTimer (window, event_id, interval, callback);
To use a callback:
timer_id = SetTimer (NULL, NULL, interval_in_milliseconds, callback);
To get a WM_TIMER message to a window:
timer_id = SetTimer (window, event_id, interval_in_milliseconds, NULL);
In both cases, the calling thread needs to have a message queue as both variants issue a WM_TIMER message, the default handler calls the callback function.
Depending on the OS you're using the value of interval has upper and lower bounds. See the API documentation for more details.
To release the timer after you're finished with it do the following if you provided a window handle:
KillTimer (window, event_id); // event_id is important!
and if you used a callback:
KillTimer (NULL, timer_id);
A single window can have many timers associated with it, use a different event_id for each timer. Reusing an event_id stops the first instance of the timer without posting the WM_TIMER message.
Pros: fairly easy to use.
Cons: latency between interval end and processing of WM_TIMER message, resolution is large, requires a message processing loop.

Another method for handling timers is to use waitable timer objects. These don't require any message processing, don't use WM_TIMER or callbacks. As such, they're a bit more complex. Understanding the Windows event system will be helpful.
There are three types of timer objects: manual-reset, synchronisation and periodic; and there are four functions for handling the timer objects: CreateWaitableTimer, SetWaitableTimer, CancelWaitableTimer and CloseHandle (there is a fifth, OpenWaitableTimer but that is unlikely to useful to many people). There are also a set of functions required for notification of when a timer expires: WaitForSingleObject, MsgWaitForSingleObject, WaitForMultipleObjects and MsgWaitForMultipleObjects being the most useful.
The usual method for using these timers is:
CreateWaitableTimer (...)
SetWaitableTimer (...)
WaitForSingleObject (...)
CloseHandle (...)
Compare this to SetTimer - the only way to know if a timer has expired is to poll it, either in a loop or with an infinte timeout (i.e. suspend the thread until the timer elapses).
Pros: very flexible, no need to have a message queue.
Cons: hard to use

Usually, look at the API you are going to use, for example MFC, Qt or GTK; they all have timer classes.
If you're not going to use a GUI API, I personally like boost::timer (www.boost.org)

For high resolution timers, use queryperformancecounter

Related

Synchronization primitives in DriverKit

In a DriverKit extension, I would like to block a call from a user client until a specific hardware interrupt fires. Since there are no semaphores available (Does the DriverKit SDK support semaphores?), I've reached for a very basic spinlock using an _Atomic(bool) member and busy waiting:
struct IVars
{
volatile _Atomic(bool) InterruptOccurred = false;
}
// In the user client method handler
{
// Clear the flag
atomic_store(&ivars->InterruptOccurred, false);
// Set up the interrupt on the device
...
// Wait for the interrupt
while (!atomic_load(&ivars->InterruptOccurred))
{
IOSleep(10);
}
}
// In the interrupt handler
{
bool expected = false;
if (atomic_compare_exchange_strong(&ivars->InterruptOccurred, &expected, true))
{
return;
}
// Proceed with normal handling if the user client method is not waiting
}
The user client method is called infrequently and the interrupt is guaranteed to fire within 100ms, so in principle busy waiting should be acceptable, but I am not very happy with the solution. I haven't worked with spinlocks before and they make me feel rather uneasy.
I would like to avoid taking an IOLock in the interrupt handler. Is there any other synchronization primitive in DriverKit I could reach for? I guess a cleaner way to handle this would be for the user client method to accept a callback that fires on the interrupt, but that would still require synchronization with the interrupt handler and would complicate the client application code.
Preliminaries
I would like to avoid taking an IOLock in the interrupt handler.
I assume you're aware that, this being DriverKit, this isn't running in the context of a primary interrupt controller, but you're already behind a layer of Mach messaging, kernel/user context switch, and IODispatchQueue serialisation?
Possible solutions:
Since there are no semaphores available[…]
OSAction
The OSAction class contains a set of methods for sleeping in a thread until the action is invoked. (WillWait/Wait/EndWait) This might be a feasible way of implementing what you're trying to do. As usual, the documentation is in the header/iig file but hasn't made it into the web-based API docs.
IODispatchQueue
As of DriverKit 21 (macOS 12), you also get Apple's simpler Sleep/Wakeup event system baked into IODispatchQueue, which you might be familiar with from the kernel. (It is also similar to pthreads condition variables.) Note you need to create the queue with the kIODispatchQueueReentrant option in this case.
From DriverKit 22 (macOS 13/iPadOS) on, there's also a version with a deadline for the sleep SleepWithDeadline.
Async callbacks
I guess a cleaner way to handle this would be for the user client method to accept a callback that fires on the interrupt, but that would still require synchronization with the interrupt handler and would complicate the client application code.
If you're happy calling the async callback in the app on every interrupt, there's not really any synchronisation needed, you can just invoke the same OSAction repeatedly. Even if you want to only invoke the async call on the "next" interrupt, atomic compare-and-swap should be sufficient for the interrupt handler to claim the OSAction* pointer.
Important note:
With all of these potential solutions except IODispatchQueue::Sleep and the async callback: bear in mind that sleeping in the context of a user client external method will block the dispatch queue and thus any other calls to external methods in that user client will fail to make progress. (As well as any other methods scheduled to that queue.)

When should I use a wait function like MsgWaitForMultipleObjects, and when shouldn't I?

So I am trying to understand the message processing code of Unreal Engine on Windows OS, and I didn't find any frequent usage of the function MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx in the message pumping code.
The engine message pumping goes like this:
MSG Message;
// standard Windows message handling
while(PeekMessage(&Message, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
For context, this code will run every frame one to three times, meaning the code will be executed each 2 - 5 milliseconds on average throughout the running time of the application. A) Does that make wait functions unnecessary? or am I missing something here!
B) Is there any rough estimation of how long an application could be busy doing 'other stuff' before processing incoming messages? For instance if an application only processes messages every 50 millisecond, is that a bad practice? or is that a reasonable way of doing it? And what if the period became 500 milliseconds and so?
Use MsgWaitForMultipleObjects/etc if you need to both handle window message processing and kernel handle or alertable waits in a single thread. If you are only doing message processing then simply use a normal GetMessage based message loop, if only doing kernel handle or alertable waits then use WaitForMultipleObjects as appropriate.

implement Windows timer

how would one implement a C++ timer function which would act like:
void glutTimerFunc(unsigned int msecs,void (*func)(int value), value); but was purely WinAPI (or STL) stuff? I need it to not busy wait, though. It needs to call a function after X number of milliseconds Thank you for any/all help!
I've been looking at struct timeval tv; but I'm al little confused about how to actually implement it. It needs to be a drop in replacement for glutTimerFunc(). Thanks
Use Waitable Timers - SetWaitableTimer after calling CreateWaitableTimer
When the due time arrives, the timer is signaled and the thread that
set the timer calls the optional completion routine.
There is an example of what I think is your desired usage pattern here.

Timer Queues, immediately terminate a timer?

I'm trying to achieve high frame-per-second on Windows GDI by using Windows Timer Queues. The relevant APIs are CreateTimerQueue, DeleteTimerQueueEx, CreateTimerQueueTimer, and DeleteTimerQueueTimer .
The timer is created using CreateTimerQueueTimer(&m_timer, m_timer_queue, TimerCallback, this, 0, 20, WT_EXECUTEINTIMERTHREAD); to achieve some 50fps of speed. GDI operations (some painting in the backstore, plus InvalidateRect) cannot be asynchronous, therefore I can't choose other flags but WT_EXECUTEINTIMERTHREAD so that no extra sync op is required on the drawing code. The idea is to achieve 50fps when possible, and when it's not, just show each frame at the maximum possible speed.
At the end of the animation (reached a total frame count), DeleteTimerQueueTimer is called to destroy the timer.
The problem is that DeleteTimerQueueTimer doesn't immediately turn off the callings of the callback function. When it's not possible to achieve the 50fps requirement, the timer pumps the call into a queue. Calling DeleteTimerQueueTimer inside the callback function doesn't destroy the queue. As a result, the callback is still being called even though it decided to shutdown the timer.
How do I deal with this problem?
-
On another note, the old timeSetEvent / timeKillEvent multimedia API doesn't seem to have this problem. There are no queues and the calling of the callback function is immediately stopped when I call timeKillEvent. Is it possible to achieve the same behavior with timer queues?
You can pass the WT_EXECUTEONLYONCE flag to the CreateTimerQueueTimer function. This will cause the timer to trigger only once and not periodically.
You can then reschedule the timer with the ChangeTimerQueueTimer method.
To cover the times where your drawing takes too long too complete in the frame, you can add a CriticalSection to the beginning of the TimerHandler method, which will cause the 2nd timer to wait until the first one completes.
If you want to run something at 50fps+, you'd probably do better to actually just have a draw loop which computes the amount of time between frames and scales the animation accordingly. Timers aren't really meant to fire so often. So (and this would probably be in your Idle handler). Like, this pseudocode (ignore lack of error handling):
static longlong last_frame;
while(1) {
longlong current_frame = QueryPerformanceCounter();
long delta = current_frame - last_frame;
// Do drawing here, scale amount to move by how much time has elapsed
last_frame = current_frame;
}
DeleteTimerQueueTimer will cancel the timer provided it has not already been scheduled. (When you use WT_EXECUTEINTIMERTHREAD I believe they are queued as an APC on a thread from a thread pool shared by the timer queues and worker threads. ) If it has already been scheduled (not just running) - it will be run and the DeleteTimerQueueTimer call will block until completion.
If I understand your problem correctly, may I suggest the following?
1. Before calling DeleteTimerQueueTimer - set a flag say abortAllTimers to true.
2. In each timer call back function check to see if abortAllTimers is true. If it is true - then return at once without doing any drawing.
And finally - DeleteTimerQueueTimer should not be called from the timer callback. Instead I would suggest you should call it from any other thread - say the thread you used to start the timers.
Hope this helps.

Win32: Get message notification of other application's close/exit

My application needs to monitor all other running applications on the system. Is there some way I could get notified on exit of every application exe?
The methods I could find:
1) Use PSAPI functions to get the list of running exes at frequent intervals. At each poll compare with the previous list to find which application/process has exited.
Disadvantage: Requires constant polling, will take CPU time.
2) Set a global hook for WM_CLOSE message: Using this I would be able to get a notification when any application gets closed through the close button on the title bar
Disadvantage:
(-)Not all the applications are generating a WM_CLOSE message(Ex: Total Video Player Exe)
(-)If the application was closed through the "Exit" menu or button (e.g. File->Exit) , I can't trap that message
Is there any other better way that I missed? Please advise.
Get a list of PIDs using PSAPI.
Then get a handle on each process using OpenProcess().
Use WaitForMultipleObjects() to be signalled when one of the processes exits.
You could try the RegisterShellHookWindow() API and filter for HSHELL_WINDOWCREATED and HSHELL_WINDOWDESTROYED messages.
Of course, that will only get you notified about applications that have a window.
I recently ran into this problem and found a solution so wanted to share with you all. It all correct the way we should obtain handle to the process. Instead of WaitForSingleOBject though, I would recommend to use RegisterWaitForSingle object function. With this function you are giving a callback function and whenever the process exits, your callback function will be called. This is better than calling WaitForSingleObject in a thread. Calling WaitForSingleObject in your code by itself will cause your code to wait until the process exits. Here is an example of how to call it:
RegisterWaitForSingleObject(&waitHandle, processHandle, ProcessTerminatedCallback, param, INFINITE, WT_EXECUTEONLYONCE);
Where:
[out]waitHandle - new handle created for you. Please note that you cannot use this handle to call CloseHandle, but you can wait on it, if you want to.
[in] processHandle - handle to the process that you are supposed to obtain yourself
[in] ProcessTerminatedCallback - the callback function that will be called when the process exits
[in] param - LPVOID parameter that will be passed to the callback
[in] INFINITE - either wait infinitely or for a specified time, look up MSDN for more info
[in] WM_EXECUTEONLYONCE - will call the callback function only once. look up MSDN for more info
> Is there any other better way that I missed?
Yes, plenty. See on Win32 group (system notifications, without any hook)

Resources