[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnurl] 19/264: select: move duplicate select preparation code into Curl
From: |
gnunet |
Subject: |
[gnurl] 19/264: select: move duplicate select preparation code into Curl_select |
Date: |
Thu, 30 Apr 2020 16:05:22 +0200 |
This is an automated email from the git hooks/post-receive script.
nikita pushed a commit to branch master
in repository gnurl.
commit c52b3420510301a62ce6a209720d57f8f41413a4
Author: Marc Hoersken <address@hidden>
AuthorDate: Sun Mar 15 11:07:08 2020 +0100
select: move duplicate select preparation code into Curl_select
Reviewed by Daniel Stenberg
Reviewed by Marcel Raad
Closes #5078
---
lib/select.c | 164 ++++++++++++++++++++++++++++++-----------------------------
lib/select.h | 6 +++
2 files changed, 89 insertions(+), 81 deletions(-)
diff --git a/lib/select.c b/lib/select.c
index b372efff1..b9d7d6569 100644
--- a/lib/select.c
+++ b/lib/select.c
@@ -100,6 +100,76 @@ int Curl_wait_ms(int timeout_ms)
return r;
}
+/*
+ * This is a wrapper around select() to aid in Windows compatibility.
+ * A negative timeout value makes this function wait indefinitely,
+ * unless no valid file descriptor is given, when this happens the
+ * negative timeout is ignored and the function times out immediately.
+ *
+ * Return values:
+ * -1 = system call error or fd >= FD_SETSIZE
+ * 0 = timeout
+ * N = number of signalled file descriptors
+ */
+int Curl_select(curl_socket_t maxfd,
+ fd_set *fds_read,
+ fd_set *fds_write,
+ fd_set *fds_err,
+ time_t timeout_ms) /* milliseconds to wait */
+{
+ struct timeval pending_tv;
+ struct timeval *ptimeout;
+ int pending_ms = 0;
+ int r;
+
+#ifdef USE_WINSOCK
+ /* WinSock select() can't handle zero events. See the comment below. */
+ if((!fds_read || fds_read->fd_count == 0) &&
+ (!fds_write || fds_write->fd_count == 0) &&
+ (!fds_err || fds_err->fd_count == 0)) {
+ r = Curl_wait_ms((int)timeout_ms);
+ return r;
+ }
+#endif
+
+ ptimeout = &pending_tv;
+
+ if(timeout_ms < 0) {
+ ptimeout = NULL;
+ }
+ else if(timeout_ms > 0) {
+ pending_ms = (int)timeout_ms;
+ pending_tv.tv_sec = pending_ms / 1000;
+ pending_tv.tv_usec = (pending_ms % 1000) * 1000;
+ }
+ else if(!timeout_ms) {
+ pending_tv.tv_sec = 0;
+ pending_tv.tv_usec = 0;
+ }
+
+#ifdef USE_WINSOCK
+ /* WinSock select() must not be called with an fd_set that contains zero
+ fd flags, or it will return WSAEINVAL. But, it also can't be called
+ with no fd_sets at all! From the documentation:
+
+ Any two of the parameters, readfds, writefds, or exceptfds, can be
+ given as null. At least one must be non-null, and any non-null
+ descriptor set must contain at least one handle to a socket.
+
+ It is unclear why WinSock doesn't just handle this for us instead of
+ calling this an error.
+ */
+ r = select((int)maxfd + 1,
+ fds_read && fds_read->fd_count ? fds_read : NULL,
+ fds_write && fds_write->fd_count ? fds_write : NULL,
+ fds_err && fds_err->fd_count ? fds_err : NULL, ptimeout);
+#else
+ r = select((int)maxfd + 1, fds_read, fds_write, fds_err, ptimeout);
+#endif
+
+ return r;
+}
+
/*
* Wait for read or write events on a set of file descriptors. It uses poll()
* when a fine poll() is available, in order to avoid limits with FD_SETSIZE,
@@ -127,16 +197,14 @@ int Curl_socket_check(curl_socket_t readfd0, /* two
sockets to read from */
{
#ifdef HAVE_POLL_FINE
struct pollfd pfd[3];
+ int pending_ms = 0;
int num;
#else
- struct timeval pending_tv;
- struct timeval *ptimeout;
fd_set fds_read;
fd_set fds_write;
fd_set fds_err;
curl_socket_t maxfd;
#endif
- int pending_ms = 0;
int r;
int ret;
@@ -158,10 +226,6 @@ int Curl_socket_check(curl_socket_t readfd0, /* two
sockets to read from */
when function is called with a zero timeout or a negative timeout
value indicating a blocking call should be performed. */
- if(timeout_ms > 0) {
- pending_ms = (int)timeout_ms;
- }
-
#ifdef HAVE_POLL_FINE
num = 0;
@@ -184,7 +248,9 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets
to read from */
num++;
}
- if(timeout_ms < 0)
+ if(timeout_ms > 0)
+ pending_ms = (int)timeout_ms;
+ else if(timeout_ms < 0)
pending_ms = -1;
else if(!timeout_ms)
pending_ms = 0;
@@ -249,46 +315,17 @@ int Curl_socket_check(curl_socket_t readfd0, /* two
sockets to read from */
maxfd = writefd;
}
- ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
-
- if(timeout_ms > 0) {
- pending_tv.tv_sec = pending_ms / 1000;
- pending_tv.tv_usec = (pending_ms % 1000) * 1000;
- }
- else if(!timeout_ms) {
- pending_tv.tv_sec = 0;
- pending_tv.tv_usec = 0;
- }
-
- /* WinSock select() must not be called with an fd_set that contains zero
- fd flags, or it will return WSAEINVAL. But, it also can't be called
- with no fd_sets at all! From the documentation:
-
- Any two of the parameters, readfds, writefds, or exceptfds, can be
- given as null. At least one must be non-null, and any non-null
- descriptor set must contain at least one handle to a socket.
-
- We know that we have at least one bit set in at least two fd_sets in
+ /* We know that we have at least one bit set in at least two fd_sets in
this case, but we may have no bits set in either fds_read or fd_write,
so check for that and handle it. Luckily, with WinSock, we can _also_
ask how many bits are set on an fd_set.
- It is unclear why WinSock doesn't just handle this for us instead of
- calling this an error.
-
Note also that WinSock ignores the first argument, so we don't worry
about the fact that maxfd is computed incorrectly with WinSock (since
curl_socket_t is unsigned in such cases and thus -1 is the largest
value).
*/
-#ifdef USE_WINSOCK
- r = select((int)maxfd + 1,
- fds_read.fd_count ? &fds_read : NULL,
- fds_write.fd_count ? &fds_write : NULL,
- &fds_err, ptimeout);
-#else
- r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
-#endif
+ r = Curl_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms);
if(r < 0)
return -1;
@@ -336,9 +373,9 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets
to read from */
*/
int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
{
-#ifndef HAVE_POLL_FINE
- struct timeval pending_tv;
- struct timeval *ptimeout;
+#ifdef HAVE_POLL_FINE
+ int pending_ms = 0;
+#else
fd_set fds_read;
fd_set fds_write;
fd_set fds_err;
@@ -346,7 +383,6 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int
timeout_ms)
#endif
bool fds_none = TRUE;
unsigned int i;
- int pending_ms = 0;
int r;
if(ufds) {
@@ -367,13 +403,11 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds,
int timeout_ms)
when function is called with a zero timeout or a negative timeout
value indicating a blocking call should be performed. */
- if(timeout_ms > 0) {
- pending_ms = timeout_ms;
- }
-
#ifdef HAVE_POLL_FINE
- if(timeout_ms < 0)
+ if(timeout_ms > 0)
+ pending_ms = timeout_ms;
+ else if(timeout_ms < 0)
pending_ms = -1;
else if(!timeout_ms)
pending_ms = 0;
@@ -418,39 +452,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int
timeout_ms)
}
}
-#ifdef USE_WINSOCK
- /* WinSock select() can't handle zero events. See the comment about this in
- Curl_check_socket(). */
- if(fds_read.fd_count == 0 && fds_write.fd_count == 0
- && fds_err.fd_count == 0) {
- r = Curl_wait_ms(timeout_ms);
- return r;
- }
-#endif
-
- ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
-
- if(timeout_ms > 0) {
- pending_tv.tv_sec = pending_ms / 1000;
- pending_tv.tv_usec = (pending_ms % 1000) * 1000;
- }
- else if(!timeout_ms) {
- pending_tv.tv_sec = 0;
- pending_tv.tv_usec = 0;
- }
-
-#ifdef USE_WINSOCK
- r = select((int)maxfd + 1,
- /* WinSock select() can't handle fd_sets with zero bits set, so
- don't give it such arguments. See the comment about this in
- Curl_check_socket().
- */
- fds_read.fd_count ? &fds_read : NULL,
- fds_write.fd_count ? &fds_write : NULL,
- fds_err.fd_count ? &fds_err : NULL, ptimeout);
-#else
- r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
-#endif
+ r = Curl_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms);
if(r < 0)
return -1;
diff --git a/lib/select.h b/lib/select.h
index ec3021aac..56fe30367 100644
--- a/lib/select.h
+++ b/lib/select.h
@@ -72,6 +72,12 @@ struct pollfd
therefore defined here */
#define CURL_CSELECT_IN2 (CURL_CSELECT_ERR << 1)
+int Curl_select(curl_socket_t maxfd,
+ fd_set *fds_read,
+ fd_set *fds_write,
+ fd_set *fds_err,
+ time_t timeout_ms);
+
int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
curl_socket_t writefd,
time_t timeout_ms);
--
To stop receiving notification emails like this one, please contact
address@hidden.
- [gnurl] 04/264: Makefile: run the cd commands in a subshell, (continued)
- [gnurl] 04/264: Makefile: run the cd commands in a subshell, gnunet, 2020/04/30
- [gnurl] 06/264: RELEASE-NOTES: synced, gnunet, 2020/04/30
- [gnurl] 09/264: smbserver: pin Python version to 2 since we are not yet 3 compatible, gnunet, 2020/04/30
- [gnurl] 10/264: impacket: some more Python 3 code compatibility updates, gnunet, 2020/04/30
- [gnurl] 08/264: cleanup: fix some text/comment typos, gnunet, 2020/04/30
- [gnurl] 05/264: tests/data: Fix some XML formatting issues in test cases, gnunet, 2020/04/30
- [gnurl] 11/264: server/getpart: make the "XML-parser" stricter, gnunet, 2020/04/30
- [gnurl] 13/264: easy: Fix curl_easy_duphandle for builds missing IPv6 that use c-ares, gnunet, 2020/04/30
- [gnurl] 17/264: ci/tests: fix and align setting TFLAGS for make test-nonflaky, gnunet, 2020/04/30
- [gnurl] 14/264: Makefile.m32: Improve windres parameter compatibility, gnunet, 2020/04/30
- [gnurl] 19/264: select: move duplicate select preparation code into Curl_select,
gnunet <=
- [gnurl] 24/264: tests/README: add note about manually installing python-impacket, gnunet, 2020/04/30
- [gnurl] 23/264: transfer: cap retries of "dead connections" to 5, gnunet, 2020/04/30
- [gnurl] 25/264: ci/tests: install impacket for SMB tests on FreeBSD using CirrusCI, gnunet, 2020/04/30
- [gnurl] 20/264: select: fix 'pending_ms' is assigned a value that is never used, gnunet, 2020/04/30
- [gnurl] 27/264: gskit: use our internal select wrapper for portability, gnunet, 2020/04/30
- [gnurl] 29/264: ci/tests: fix Azure Pipelines not running for pull requests, gnunet, 2020/04/30
- [gnurl] 28/264: gskit: update the copyright year range, gnunet, 2020/04/30
- [gnurl] 31/264: tool_operate: fix add_parallel_transfers when more are in queue, gnunet, 2020/04/30
- [gnurl] 38/264: writeout_json: add missing comma to fix the HTTP version, gnunet, 2020/04/30
- [gnurl] 18/264: connect: happy eyeballs cleanup, gnunet, 2020/04/30