Click to See Complete Forum and Search --> : Favorite subject :) Will this cause a race condition?


ahmd
October 22nd, 2010, 05:33 AM
I'm trying to better understand the workings of the WaitForMultipleObjects API. Say, I have two objects:

HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); //Auto reset
HANDLE hWaitableTimer = CreateWaitableTimer(NULL, FALSE, NULL); //Auto reset


then the timer is set to some time in the future:
LARGE_INTEGER li;
li.QuadPart = -100000000LL; //10 seconds in the future
SetWaitableTimer(hWaitableTimer, &li, 0, NULL, NULL, 0);

and the event can be set by some other thread, say, at a random time.

Then I have the following worker thread that waits for these events:

enum
{
EVENT_ID,
TIMER_ID,

EVENTS_COUNT,
};

HANDLE hObjects[EVENTS_COUNT];
hObjects[EVENT_ID] = hEvent;
hObjects[TIMER_ID] = hWaitableTimer;

for(;;)
{
DWORD nResObj = WaitForMultipleObjects(EVENTS_COUNT, hObjects, FALSE, INFINITE) - WAIT_OBJECT_0;

if(nResObj == EVENT_ID)
{
//Event is signaled
DoEventSignaledProcessing();
}
else if(nResObj == TIMER_ID)
{
//Timer is signaled
DoTimerSignaledProcessing();
}
else
{
//Error
}
}



So my question is, does the fact that both timer & event are auto reset create a race condition when I use them both in the WaitForMultipleObjects API? Say, in a situation when they both become signaled at the same time, so WaitForMultipleObjects() returns the index 0 of the event but will the timer's signaled state also be accounted for, or will I miss DoTimerSignaledProcessing() in this situation? I'm not very clear on this one...

Alex F
October 22nd, 2010, 06:04 AM
This code is OK, auto reset is default mode which should be always used unless you need some special reason to use manual reset. In the case two waitable objects are signaled, WaitForMultipleObjects returns each of them in two iterations, none of signaled objects is not missed.
Manual reset event may be missed by wait function. Consider situation, when wait function returns and then event is reset:

WaitForSingleObject(hEvent);
// if event is set here in another thread, it is lost
ResetEvent(hEvent);

ahmd
October 22nd, 2010, 12:31 PM
Yes. I thought so too. Thanks for checking.