[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnurl] 25/411: multi: expand pre-check for socket readiness
From: |
gnunet |
Subject: |
[gnurl] 25/411: multi: expand pre-check for socket readiness |
Date: |
Wed, 13 Jan 2021 01:17:20 +0100 |
This is an automated email from the git hooks/post-receive script.
nikita pushed a commit to branch master
in repository gnurl.
commit 3334ee6bcb2b23c583f4601dc24d122bb9719f17
Author: Marc Hoersken <info@marc-hoersken.de>
AuthorDate: Sun Jul 26 21:26:46 2020 +0200
multi: expand pre-check for socket readiness
Check readiness of all sockets before waiting on them
to avoid locking in case the one-time event FD_WRITE
was already consumed by a previous wait operation.
More information about WinSock network events:
https://docs.microsoft.com/en-us/windows/win32/api/
winsock2/nf-winsock2-wsaeventselect#return-value
Closes #5634
---
lib/multi.c | 72 +++++++++++++++++++++++++++++--------------------------------
1 file changed, 34 insertions(+), 38 deletions(-)
diff --git a/lib/multi.c b/lib/multi.c
index c8bba47f6..00eb4dd69 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -1094,7 +1094,7 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
struct pollfd *ufds = &a_few_on_stack[0];
bool ufds_malloc = FALSE;
#else
- int already_writable = 0;
+ struct pollfd pre_poll;
DEBUGASSERT(multi->wsa_event != WSA_INVALID_EVENT);
#endif
@@ -1175,13 +1175,15 @@ static CURLMcode Curl_multi_wait(struct Curl_multi
*multi,
while(data) {
bitmap = multi_getsock(data, sockbunch);
- for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
+ for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) {
curl_socket_t s = CURL_SOCKET_BAD;
#ifdef USE_WINSOCK
long mask = 0;
#endif
if(bitmap & GETSOCK_READSOCK(i)) {
#ifdef USE_WINSOCK
+ if(SOCKET_READABLE(sockbunch[i], 0) > 0)
+ timeout_ms = 0;
mask |= FD_READ;
#else
ufds[nfds].fd = sockbunch[i];
@@ -1192,15 +1194,8 @@ static CURLMcode Curl_multi_wait(struct Curl_multi
*multi,
}
if(bitmap & GETSOCK_WRITESOCK(i)) {
#ifdef USE_WINSOCK
- struct timeval timeout;
- fd_set writefds;
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- FD_ZERO(&writefds);
- FD_SET(sockbunch[i], &writefds);
- if(select((int)sockbunch[i] + 1, NULL, &writefds, NULL,
- &timeout) == 1)
- already_writable++;
+ if(SOCKET_WRITABLE(sockbunch[i], 0) > 0)
+ timeout_ms = 0;
mask |= FD_WRITE;
#else
ufds[nfds].fd = sockbunch[i];
@@ -1227,23 +1222,30 @@ static CURLMcode Curl_multi_wait(struct Curl_multi
*multi,
#ifdef USE_WINSOCK
long events = 0;
extra_fds[i].revents = 0;
- if(extra_fds[i].events & CURL_WAIT_POLLIN)
+ pre_poll.fd = extra_fds[i].fd;
+ pre_poll.events = 0;
+ pre_poll.revents = 0;
+ if(extra_fds[i].events & CURL_WAIT_POLLIN) {
events |= FD_READ;
- if(extra_fds[i].events & CURL_WAIT_POLLPRI)
+ pre_poll.events |= POLLIN;
+ }
+ if(extra_fds[i].events & CURL_WAIT_POLLPRI) {
events |= FD_OOB;
+ pre_poll.events |= POLLPRI;
+ }
if(extra_fds[i].events & CURL_WAIT_POLLOUT) {
- struct timeval timeout;
- fd_set writefds;
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- FD_ZERO(&writefds);
- FD_SET(extra_fds[i].fd, &writefds);
- if(select((int)extra_fds[i].fd + 1, NULL, &writefds, NULL,
- &timeout) == 1) {
- extra_fds[i].revents = CURL_WAIT_POLLOUT;
- already_writable++;
- }
events |= FD_WRITE;
+ pre_poll.events |= POLLOUT;
+ }
+ if(Curl_poll(&pre_poll, 1, 0) > 0) {
+ if(pre_poll.revents & POLLIN)
+ extra_fds[i].revents |= CURL_WAIT_POLLIN;
+ if(pre_poll.revents & POLLOUT)
+ extra_fds[i].revents |= CURL_WAIT_POLLOUT;
+ if(pre_poll.revents & POLLPRI)
+ extra_fds[i].revents |= CURL_WAIT_POLLPRI;
+ if(extra_fds[i].revents)
+ timeout_ms = 0;
}
if(WSAEventSelect(extra_fds[i].fd, multi->wsa_event, events) != 0)
return CURLM_INTERNAL_ERROR;
@@ -1273,8 +1275,6 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
if(nfds) {
/* wait... */
#ifdef USE_WINSOCK
- if(already_writable > 0)
- timeout_ms = 0;
WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE);
#else
int pollrc = Curl_poll(ufds, nfds, timeout_ms);
@@ -1306,7 +1306,7 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
if(events.lNetworkEvents & FD_OOB)
mask |= CURL_WAIT_POLLPRI;
- if(events.lNetworkEvents != 0)
+ if(ret && events.lNetworkEvents != 0)
retcode++;
}
WSAEventSelect(extra_fds[i].fd, multi->wsa_event, 0);
@@ -1337,19 +1337,15 @@ static CURLMcode Curl_multi_wait(struct Curl_multi
*multi,
WSANETWORKEVENTS events = {0};
if(WSAEnumNetworkEvents(sockbunch[i], multi->wsa_event,
&events) == 0) {
- if(events.lNetworkEvents != 0)
+ if(ret && events.lNetworkEvents != 0)
retcode++;
}
- if(ret && !events.lNetworkEvents &&
- (bitmap & GETSOCK_WRITESOCK(i))) {
- struct timeval timeout;
- fd_set writefds;
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- FD_ZERO(&writefds);
- FD_SET(sockbunch[i], &writefds);
- if(select((int)sockbunch[i] + 1, NULL, &writefds, NULL,
- &timeout) == 1)
+ if(ret && !timeout_ms && !events.lNetworkEvents) {
+ if((bitmap & GETSOCK_READSOCK(i)) &&
+ SOCKET_READABLE(sockbunch[i], 0) > 0)
+ retcode++;
+ else if((bitmap & GETSOCK_WRITESOCK(i)) &&
+ SOCKET_WRITABLE(sockbunch[i], 0) > 0)
retcode++;
}
WSAEventSelect(sockbunch[i], multi->wsa_event, 0);
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [gnurl] 09/411: runtests: make cleardir() erase dot files too, (continued)
- [gnurl] 09/411: runtests: make cleardir() erase dot files too, gnunet, 2021/01/12
- [gnurl] 05/411: runtests: clear pid variables when failing to start a server, gnunet, 2021/01/12
- [gnurl] 02/411: RELEASE-NOTES: synced, gnunet, 2021/01/12
- [gnurl] 03/411: dist: add missing CMake Find modules to the distribution, gnunet, 2021/01/12
- [gnurl] 01/411: tls: provide the CApath verbose log on its own line, gnunet, 2021/01/12
- [gnurl] 07/411: Makefile.m32: add ability to override zstd libs [ci skip], gnunet, 2021/01/12
- [gnurl] 06/411: runtests: avoid 'fail to start' repeated messages in attempt loops, gnunet, 2021/01/12
- [gnurl] 08/411: KNOWN_BUGS: 'no_proxy' string-matches IPv6 numerical addreses, gnunet, 2021/01/12
- [gnurl] 33/411: curl_get_line: build only if cookies or alt-svc are enabled, gnunet, 2021/01/12
- [gnurl] 04/411: TODO: Virtual external sockets, gnunet, 2021/01/12
- [gnurl] 25/411: multi: expand pre-check for socket readiness,
gnunet <=
- [gnurl] 14/411: curl: support XDG_CONFIG_HOME to find .curlrc, gnunet, 2021/01/12
- [gnurl] 20/411: docs: --output-dir is added in 7.73.0, nothing else, gnunet, 2021/01/12
- [gnurl] 34/411: socketpair: allow CURL_DISABLE_SOCKETPAIR, gnunet, 2021/01/12
- [gnurl] 22/411: select: fix poll-based check not detecting connect failure, gnunet, 2021/01/12
- [gnurl] 21/411: select.h: make socket validation macros test for INVALID_SOCKET, gnunet, 2021/01/12
- [gnurl] 23/411: select: reduce duplication of Curl_poll in Curl_socket_check, gnunet, 2021/01/12
- [gnurl] 28/411: winbuild/README.md: make <options> visible, gnunet, 2021/01/12
- [gnurl] 31/411: git: ignore libtests in 3XXX area, gnunet, 2021/01/12
- [gnurl] 26/411: lib1560: verify "redirect" to double-slash leading URL, gnunet, 2021/01/12
- [gnurl] 17/411: sftp: add the option CURLKHSTAT_FINE_REPLACE, gnunet, 2021/01/12