Skip to content

Commit 2efe6c3

Browse files
committed
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 Assisted-by: Jay Satiro Tested-by: Tommy Odom Tested-by: tmkk on github Bug: curl#6146 Part of curl#6245
1 parent 2ad03d8 commit 2efe6c3

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

lib/multi.c

+13-6
Original file line numberDiff line numberDiff line change
@@ -1174,24 +1174,27 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
11741174
long mask = 0;
11751175
#endif
11761176
if(bitmap & GETSOCK_READSOCK(i)) {
1177+
s = sockbunch[i];
11771178
#ifdef USE_WINSOCK
11781179
mask |= FD_READ|FD_ACCEPT|FD_CLOSE;
11791180
#endif
1180-
ufds[nfds].fd = sockbunch[i];
1181+
ufds[nfds].fd = s;
11811182
ufds[nfds].events = POLLIN;
11821183
++nfds;
1183-
s = sockbunch[i];
11841184
}
11851185
if(bitmap & GETSOCK_WRITESOCK(i)) {
1186+
s = sockbunch[i];
11861187
#ifdef USE_WINSOCK
11871188
mask |= FD_WRITE|FD_CONNECT|FD_CLOSE;
1189+
send(s, NULL, 0, 0); /* reset FD_WRITE */
11881190
#endif
1189-
ufds[nfds].fd = sockbunch[i];
1191+
ufds[nfds].fd = s;
11901192
ufds[nfds].events = POLLOUT;
11911193
++nfds;
1192-
s = sockbunch[i];
11931194
}
1195+
/* s is only set if either being readable or writable is checked */
11941196
if(s == CURL_SOCKET_BAD) {
1197+
/* break on entry not checked for being readable or writable */
11951198
break;
11961199
}
11971200
#ifdef USE_WINSOCK
@@ -1215,8 +1218,10 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
12151218
mask |= FD_READ|FD_ACCEPT|FD_CLOSE;
12161219
if(extra_fds[i].events & CURL_WAIT_POLLPRI)
12171220
mask |= FD_OOB;
1218-
if(extra_fds[i].events & CURL_WAIT_POLLOUT)
1221+
if(extra_fds[i].events & CURL_WAIT_POLLOUT) {
12191222
mask |= FD_WRITE|FD_CONNECT|FD_CLOSE;
1223+
send(extra_fds[i].fd, NULL, 0, 0); /* reset FD_WRITE */
1224+
}
12201225
if(WSAEventSelect(extra_fds[i].fd, multi->wsa_event, mask) != 0) {
12211226
if(ufds_malloc)
12221227
free(ufds);
@@ -1317,8 +1322,10 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
13171322
}
13181323
WSAEventSelect(sockbunch[i], multi->wsa_event, 0);
13191324
}
1320-
else
1325+
else {
1326+
/* break on entry not checked for being readable or writable */
13211327
break;
1328+
}
13221329
}
13231330

13241331
data = data->next;

0 commit comments

Comments
 (0)