My application currently runs 6-8 threads concurrently depending on how it is configured. Each thread uses a custom waitable timer class that I wrote to get a 20 mS loop timing. Furthermore, Each thread lives for the life of the application.
The issue I am having is that some of the threads lock up on the WaitForSingleObject() call on the windows waitable timer interface after X amount of time. X varies.
// precision timer class
class PrecisionTimer
{
public:
PrecisionTimer() : mMilli(-1), mHandle(NULL){}
virtual ~PrecisionTimer(){ close(); }
// free the handle
void close()
{
// free up any existing handles / timers
if (mHandle != NULL){
CancelWaitableTimer(mHandle);
CloseHandle(mHandle);
mHandle = NULL;
}
}
// start the timer
bool start(constunsignedint& milli)
{
// create the timer
if (!create())
returnfalse;
// set the internal variables
mMilli = milli; // mS time
// get the system time
SYSTEMTIME cTime; // System time structure
GetSystemTime(&cTime); // Curren time
cTime.wMilliseconds += mMilli; // Wait 3 sec
// get the file time expected by waitable timer
FILETIME fileTime;
SystemTimeToFileTime(&cTime, &fileTime);
// set the waitable timer
return SetWaitableTimer(mHandle, reinterpret_cast<LARGE_INTEGER>(&fileTime), mMilli, NULL, NULL, 0);
}
// stop the timer
void stop()
{
// check if the handle exists...
if (mHandle)
CancelWaitableTimer(mHandle); // Stop timer
}
// wait for timer to expire
bool wait()
{
// wait for the timer to fire...
if (mHandle){
switch (WaitForSingleObject(mHandle, mMilli)){
case WAIT_ABANDONED:
case WAIT_OBJECT_0:
case WAIT_TIMEOUT: returntrue;
case WAIT_FAILED: returnfalse;
}
}
elsereturnfalse;
}
private:
bool create()
{
// close any existing timers
close();
// create the timer handle
mHandle = CreateWaitableTimer(NULL, FALSE, NULL);
return mHandle != NULL ? true : false;
}
unsignedint mMilli;
protected:
HANDLE mHandle;
};
Here is an example of the how I am using the timer:
1 2 3 4 5 6 7 8 9 10
void MyThread::run()
{
// set the timer settings
PrecisionTimer taskTimer;
taskTimer.start(20); // 20mS
while (true){
// do process
taskTimer.wait();
}
}
Are their any limitations I am missing with the waitable timer or to many handles from separate threads? Or maybe an operating system limitation?
NOTE: The thread that it happens the most on (lock up) is doing processing from an RS232 port. I am using Window 8 64-bit with MSVC2010
You can call it a personal preference if you want but I have always hated timers. Are you sure that there isn't another synchronization method you could use? My first thought is that depending on a number of things it isn't entirely unreasonable to suspect that more then 20 mS have passed between the creation of your timer and it's call to "WaitForSingleObject()" so the object may already be signaled by that point in which case the behavior of that wait function is undefined. What are the threads these timers get attached to doing?