multi_wait: fix and improve Curl_poll error handling on Windows

First check for errors and return CURLM_UNRECOVERABLE_POLL
before moving forward and waiting on socket readiness events.

Reviewed-by: Jay Satiro
Reviewed-by: Marcel Raad

Reported-by: Daniel Stenberg
Ref: #9361

Follow up to #8961
Closes #9372
This commit is contained in:
Marc Hoersken 2022-08-26 00:06:34 +02:00
parent a71fe41d2f
commit bc25c9e3ee
No known key found for this signature in database
GPG Key ID: 61E03CBED7BC859E

View File

@ -1343,8 +1343,6 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
pollrc = Curl_poll(ufds, nfds, 0); /* just pre-check with WinSock */
else
pollrc = 0;
if(pollrc <= 0) /* now wait... if not ready during the pre-check above */
WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE);
#else
pollrc = Curl_poll(ufds, nfds, timeout_ms); /* wait... */
#endif
@ -1355,6 +1353,9 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
retcode = pollrc;
#ifdef USE_WINSOCK
}
else { /* now wait... if not ready during the pre-check (pollrc == 0) */
WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE);
}
/* With WinSock, we have to run the following section unconditionally
to call WSAEventSelect(fd, event, 0) on all the sockets */
{
@ -1375,11 +1376,11 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
mask |= CURL_WAIT_POLLOUT;
if(wsa_events.lNetworkEvents & FD_OOB)
mask |= CURL_WAIT_POLLPRI;
if(ret && pollrc <= 0 && wsa_events.lNetworkEvents)
if(ret && !pollrc && wsa_events.lNetworkEvents)
retcode++;
}
WSAEventSelect(s, multi->wsa_event, 0);
if(pollrc <= 0) {
if(!pollrc) {
extra_fds[i].revents = mask;
continue;
}
@ -1405,7 +1406,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
if(bitmap & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))) {
wsa_events.lNetworkEvents = 0;
if(WSAEnumNetworkEvents(sockbunch[i], NULL, &wsa_events) == 0) {
if(ret && pollrc <= 0 && wsa_events.lNetworkEvents)
if(ret && !pollrc && wsa_events.lNetworkEvents)
retcode++;
}
WSAEventSelect(sockbunch[i], multi->wsa_event, 0);