diff options
author | Marc Hoersken <info@marc-hoersken.de> | 2020-12-15 07:22:13 +0100 |
---|---|---|
committer | Marc Hoersken <info@marc-hoersken.de> | 2021-04-21 20:32:24 +0200 |
commit | b36442b24305f3cda7c13cc64b46838995a4985b (patch) | |
tree | e0e64079d24b24b357dc472c1591e9887c2799f6 | |
parent | e92998a3121ac0752d86fd90d9d6053af760048e (diff) | |
download | curl-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.c | 19 |
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; |