gnunet-svn
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]