I'm using timer queues in my application, and pass a pointer to one of my own C++ Timer objects as the 'parameter' to the callback (in CreateTimerQueueTimer). I then call a virtual method on the object in the callback.
The destructor of the Timer object will make sure to cancel the timer using DeleteTimerQueueTimer().
static void callback( PVOID param, BOOLEAN timerOrWaitFired )
{
Timer* timer = reinterpret_cast< Timer* >( param );
timer->TimedOut();
}
class Timer
{
public:
Timer();
virtual ~Timer()
{
::DeleteTimerQueueTimer( handle );
}
void Start( double period )
{
::CreateTimerQueueTimer( &handle, ..., &callback, this, ... );
}
virtual void TimedOut() = 0;
...
};
However, there is a subtle race condition that if the callback has already been called, but the timer object is destroyed before the call to TimedOut(), the app crashes because the callback calls the virtual method on a non-existent object. Or even worse, while it's being deleted.
I do have mutexes in place to control multi-threaded calls, but I still get the problem.
Is using an object pointer as the callback parameter really a good idea? With no guarantees of synchronisation between the threads, it just smells bad to me.
Is there a better solution? What do other people do?
One thing that occurs is to keep a set of pointers to every single Timer instance (add in constructor, remove in destructor). But I don't think this would work because if Timer is derived from, we'd only remove the pointer from the set in the base class destructor; the damage is already done if we've started destroying the derived object.
Cheers.