The fact that WSA_WAIT_EVENT_0
is defined as 0 is irrelevant (it is just an alias for WAIT_OBJECT_0
from the WaitFor(Single|Multiple)Object(s)()
API, which is also defined as 0 - WSAWaitForMultipleEvents()
is itself just a wrapper for WaitForMultipleObjectsEx()
, though Microsoft reserves the right to change the implementation in the future without breaking existing user code).
WSAWaitForMultipleEvents()
can operate on multiple events at a time, and its return value will be one of the following possibilities:
WSA_WAIT_EVENT_0 .. (WSA_WAIT_EVENT_0 + cEvents - 1)
A specific event object was signaled.
WSA_WAIT_IO_COMPLETION
One or more alertable I/O completion routines were executed.
WSA_WAIT_TIMEOUT
A timeout occurred.
WSA_WAIT_FAILED
The function failed.
Typically, code should be looking at the return value and act accordingly, eg:
DWORD ReturnValue = WSAWaitForMultipleEvents(...);
if ((ReturnValue >= WSA_WAIT_EVENT_0) && (ReturnValue < (WSA_WAIT_EVENT_0 + EventTotal))
{
DWORD Index = ReturnValue - WSA_WAIT_EVENT_0;
// handle event at Index as needed...
}
else if (ReturnValue == WSA_WAIT_IO_COMPLETION)
{
// handle I/O as needed...
}
else if (RetunValue == WSA_WAIT_TIMEOUT)
{
// handle timeout as needed...
}
else
{
// handle error as needed...
}
Which can be simplified given the fact that bAlertable
is FALSE
(no I/O routines can be called) and dwTimeout
is WSA_INFINITE
(no timeout can elapse), so there are only 2 possible outcomes - an event is signaled or an error occurred:
DWORD ReturnValue = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, FALSE);
if (ReturnValue != WSA_WAIT_FAILED)
{
DWORD Index = ReturnValue - WSA_WAIT_EVENT_0;
WSAResetEvent(EventArray[Index]);
}
else
{
// handle error as needed...
}