summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Hoersken <info@marc-hoersken.de>2020-12-15 07:22:13 +0100
committerMarc Hoersken <info@marc-hoersken.de>2021-04-21 20:32:24 +0200
commitb36442b24305f3cda7c13cc64b46838995a4985b (patch)
treee0e64079d24b24b357dc472c1591e9887c2799f6
parente92998a3121ac0752d86fd90d9d6053af760048e (diff)
downloadcurl-b36442b24305f3cda7c13cc64b46838995a4985b.tar.gz
multi: fix slow write/upload performance on Windows
Reset FD_WRITE by sending zero bytes which is permissible and will be treated by implementations as successful send. Without this we won't be notified in case a socket is still writable if we already received such a notification and did not send any data afterwards on the socket. This would lead to waiting forever on a writable socket being writable again. Assisted-by: Tommy Odom Reviewed-by: Jay Satiro Reviewed-by: Marcel Raad Tested-by: tmkk on github Bug: #6146 Closes #6245
-rw-r--r--lib/multi.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/lib/multi.c b/lib/multi.c
index 38af89d0d..d373ba9b3 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -1174,24 +1174,27 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
long mask = 0;
#endif
if(bitmap & GETSOCK_READSOCK(i)) {
+ s = sockbunch[i];
#ifdef USE_WINSOCK
mask |= FD_READ|FD_ACCEPT|FD_CLOSE;
#endif
- ufds[nfds].fd = sockbunch[i];
+ ufds[nfds].fd = s;
ufds[nfds].events = POLLIN;
++nfds;
- s = sockbunch[i];
}
if(bitmap & GETSOCK_WRITESOCK(i)) {
+ s = sockbunch[i];
#ifdef USE_WINSOCK
mask |= FD_WRITE|FD_CONNECT|FD_CLOSE;
+ send(s, NULL, 0, 0); /* reset FD_WRITE */
#endif
- ufds[nfds].fd = sockbunch[i];
+ ufds[nfds].fd = s;
ufds[nfds].events = POLLOUT;
++nfds;
- s = sockbunch[i];
}
+ /* s is only set if either being readable or writable is checked */
if(s == CURL_SOCKET_BAD) {
+ /* break on entry not checked for being readable or writable */
break;
}
#ifdef USE_WINSOCK
@@ -1215,8 +1218,10 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
mask |= FD_READ|FD_ACCEPT|FD_CLOSE;
if(extra_fds[i].events & CURL_WAIT_POLLPRI)
mask |= FD_OOB;
- if(extra_fds[i].events & CURL_WAIT_POLLOUT)
+ if(extra_fds[i].events & CURL_WAIT_POLLOUT) {
mask |= FD_WRITE|FD_CONNECT|FD_CLOSE;
+ send(extra_fds[i].fd, NULL, 0, 0); /* reset FD_WRITE */
+ }
if(WSAEventSelect(extra_fds[i].fd, multi->wsa_event, mask) != 0) {
if(ufds_malloc)
free(ufds);
@@ -1317,8 +1322,10 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
}
WSAEventSelect(sockbunch[i], multi->wsa_event, 0);
}
- else
+ else {
+ /* break on entry not checked for being readable or writable */
break;
+ }
}
data = data->next;