shawn
shawn

Reputation: 4223

How can I get which object timed out when using WaitForMultipleObjects?

If I'm using WaitForMultipleObjects, and the function returns WAIT_TIMEOUT, how can I get which object or objects caused the timeout to occur?

Another question I have is if multiple objects are signaled, since the return value only returns the first object that it detects as signaled, how do I get the other objects which are signaled?

#include <windows.h>
#include <stdio.h>

HANDLE ghEvents[2];

DWORD WINAPI ThreadProc( LPVOID );

int main( void )
{
    HANDLE hThread; 
    DWORD i, dwEvent, dwThreadID; 

    // Create two event objects

    for (i = 0; i < 2; i++) 
    { 
        ghEvents[i] = CreateEvent( 
            NULL,   // default security attributes
            FALSE,  // auto-reset event object
            FALSE,  // initial state is nonsignaled
            NULL);  // unnamed object

        if (ghEvents[i] == NULL) 
        { 
            printf("CreateEvent error: %d\n", GetLastError() ); 
            ExitProcess(0); 
        } 
    } 

    // Create a thread

    hThread = CreateThread( 
                 NULL,         // default security attributes
                 0,            // default stack size
                 (LPTHREAD_START_ROUTINE) ThreadProc, 
                 NULL,         // no thread function arguments
                 0,            // default creation flags
                 &dwThreadID); // receive thread identifier

    if( hThread == NULL )
    {
        printf("CreateThread error: %d\n", GetLastError());
        return 1;
    }

    // Wait for the thread to signal one of the event objects

    dwEvent = WaitForMultipleObjects( 
        2,           // number of objects in array
        ghEvents,     // array of objects
        FALSE,       // wait for any object
        5000);       // five-second wait

    // The return value indicates which event is signaled

    switch (dwEvent) 
    { 
        // ghEvents[0] was signaled
        case WAIT_OBJECT_0 + 0: 
            // TODO: Perform tasks required by this event
            printf("First event was signaled.\n");
            break; 

        // ghEvents[1] was signaled
        case WAIT_OBJECT_0 + 1: 
            // TODO: Perform tasks required by this event
            printf("Second event was signaled.\n");
            break; 

        case WAIT_TIMEOUT:
            // How can I get which object timed out?
            printf("Wait timed out.\n");
            break;

        // Return value is invalid.
        default: 
            printf("Wait error: %d\n", GetLastError()); 
            ExitProcess(0); 
    }

    // Close event handles

    for (i = 0; i < 2; i++) 
        CloseHandle(ghEvents[i]); 

    return 0;   
}

DWORD WINAPI ThreadProc( LPVOID lpParam )
{

    // lpParam not used in this example
    UNREFERENCED_PARAMETER( lpParam);

    // Set one event to the signaled state

    if ( !SetEvent(ghEvents[0]) ) 
    {
        printf("SetEvent failed (%d)\n", GetLastError());
        return 1;
    }
    return 0;
}

Upvotes: 1

Views: 3166

Answers (1)

Frank Bollack
Frank Bollack

Reputation: 25176

When the WaitForMultipleObjects(...) returns with the WAIT_TIMEOUT return code, it indicates that none of your you objects you waited for signaled within the given amount of time.

The function essentially sleeps for the time you specify as timeout and only returns earlier, if one of the waitable objects gets signaled before that time. That means that the WAIT_TIMEOUT return code is not associated with any of the objects you wait for.

Your second question is partialy answered by Eregriths comment. To check if other objects are also signaled, you could call WaitForMultipleObjects(...) again, and depending on your needs, set the timeout value to 0 (do not wait). When WaitForMultipleObjects(...) returns with WAIT_TIMEOUT you know that no other objects were in a signaled state at the time of your call, but you should keep in mind, that the object, that caused your first call to return could potentially be signaled again. So you could either exclude it from your array or simply check a single object for its state with the WaitForSingleObject(...) function.

If you want to make sure all objects are signaled, you can also play with the bWaitAll parameter. WaitForMultipleObjects(...) will then only return if all your objects are in a signaled state.,

Hope that helps a bit.

Upvotes: 8

Related Questions