tags:

views:

133

answers:

3

I'm creating 3 events with the following function:

HANDLE WINAPI CreateEvent(...);

I'm waiting on all (bWaitAll is set to TRUE) event objects or a timeout with:

DWORD WINAPI WaitForMultipleObjects(...);

The return value is:

WAIT_TIMEOUT

Is there an easy way to check each event to find the one(s) that was(where) not set?

As an example :

HANDLE evt1 = ....
HANDLE evt2 = ....
HANDLE evt3 = ....

HANDLE evts[3] = ....

DWORD ret = ::WaitForMultipleObjects(3, evts, TRUE, 10000);

After 10 sec :

  • 'ret' is WAIT_TIMEOUT.
  • evt1 is set
  • evt2 is NOT set
  • evt3 is set

The return value tells me "The time-out interval elapsed and the conditions specified by the bWaitAll parameter are not satisfied.", but not which one were signaled and which one were not.

Thanks,

+3  A: 

Yes, after WaitForMultipleObjects() returned call WaitForSingleObject() for each event specifying zero timeout.

It will return WAIT_TIMEOUT for events that are not signalled and WAIT_OBJECT_0 for signalled events. Don't forget to check for WAIT_FAILED.

Surely each event state might have been changed compared to the states they had at the moment WaitFormultipleObjects() returned.

sharptooth
This kind of defeats the purpose of WaitForMultipleObjects!
anon
Since this got accepted, I should repeat here my warning that this will actually *change the state* of some Sync objects. For instance, if your "check" succeeds for a Mutex, you will also take ownership of the mutex.
T.E.D.
A: 

If your call returns WAIT_TIMEOUT it means that NONE of the objects you waited for was signalled..

anon
That would be the case if he had waitAll set to false, but he seems to have waitAll set to true (he says he waits for all events).
sharptooth
Well if he is waiting for them ALL to be signalled and it returns WAIT_TIMEOUT, they aren't all signalled, and he should wait again until they are. Either that or, as you say, use waitAll set false.
anon
+1, my error : I wasn't clear enough. I want to know which of the event failed after the WAIT_TIMEOUT returned.
Nicolas
+2  A: 

OK. Total rewrite after having the question explained to me better in the comments.

So if I'm understanding this right now, you are calling WaitForMultipleObjects with bWaitAll set to true, and when you get WAIT_TIMEOUT back from it, want to figure out which objects are holding up the works.

In that case, I'm with sharptooth, sort of. You can call WaitForSingleObject with a 0 timeout for each object. The problem with doing this is that it has side-effects for some objects. For example, if you do this on a mutex and it succeeds, you not only know it wasn't the culprit, but you now own the mutex. If that isn't what you want, you'll have to know to immediately release it.

Any apporach you take is going to be subject to race conditions. Since you are outside of the "atomic" wait call, you could go through the process and discover that now they are all ready. You could get back a set of ready/unready that isn't what you actually had inside the wait call.

Ick.

T.E.D.
It tells me which object became signaled if I use the function with "bWaitAll" at FALSE, but I'm using it with "bWaitAll" at TRUE.
Nicolas