瀏覽代碼

global_init: assume the EINTR bit by default

- Removed from global_init since it isn't thread-safe. The symbol will
  still remain to not break compiles, it just won't have any effect going
  forward.

- make the internals NOT loop on EINTR (the opposite from previously).
  It only risks returning from the select/poll/wait functions early, and that
  should be risk-free.

Closes #4840
Daniel Stenberg 4 年之前
父節點
當前提交
1ad49feb71
共有 5 個文件被更改,包括 78 次插入167 次删除
  1. 6 4
      docs/libcurl/curl_global_init.3
  2. 6 2
      lib/easy.c
  3. 64 151
      lib/select.c
  4. 1 9
      lib/select.h
  5. 1 1
      lib/sendf.c

+ 6 - 4
docs/libcurl/curl_global_init.3

@@ -5,7 +5,7 @@
 .\" *                            | (__| |_| |  _ <| |___
 .\" *                             \___|\___/|_| \_\_____|
 .\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
 .\" *
 .\" * This software is licensed as described in the file COPYING, which
 .\" * you should have received as part of this distribution. The terms
@@ -87,9 +87,11 @@ Initialise nothing extra. This sets no bit.
 A sensible default. It will init both SSL and Win32. Right now, this equals
 the functionality of the \fBCURL_GLOBAL_ALL\fP mask.
 .IP CURL_GLOBAL_ACK_EINTR
-When this flag is set, curl will acknowledge EINTR condition when connecting
-or when waiting for data.  Otherwise, curl waits until full timeout
-elapses. (Added in 7.30.0)
+This bit has no point since 7.69.0 but its behavior is instead the default.
+
+Before 7.69.0: when this flag is set, curl will acknowledge EINTR condition
+when connecting or when waiting for data.  Otherwise, curl waits until full
+timeout elapses. (Added in 7.30.0)
 .SH RETURN VALUE
 If this function returns non-zero, something went wrong and you cannot use the
 other curl functions.

+ 6 - 2
lib/easy.c

@@ -193,8 +193,12 @@ static CURLcode global_init(long flags, bool memoryfuncs)
   }
 #endif
 
-  if(flags & CURL_GLOBAL_ACK_EINTR)
-    Curl_ack_eintr = 1;
+#ifdef USE_WOLFSSH
+  if(WS_SUCCESS != wolfSSH_Init()) {
+    DEBUGF(fprintf(stderr, "Error: wolfSSH_Init failed\n"));
+    return CURLE_FAILED_INIT;
+  }
+#endif
 
   init_flags = flags;
 

+ 64 - 151
lib/select.c

@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -53,9 +53,6 @@
 /* Convenience local macros */
 #define ELAPSED_MS() (int)Curl_timediff(Curl_now(), initial_tv)
 
-int Curl_ack_eintr = 0;
-#define ERROR_NOT_EINTR(error) (Curl_ack_eintr || error != EINTR)
-
 /*
  * Internal function used for waiting a specific amount of ms
  * in Curl_socket_check() and Curl_poll() when no file descriptor
@@ -74,13 +71,6 @@ int Curl_ack_eintr = 0;
  */
 int Curl_wait_ms(int timeout_ms)
 {
-#if !defined(MSDOS) && !defined(USE_WINSOCK)
-#ifndef HAVE_POLL_FINE
-  struct timeval pending_tv;
-#endif
-  struct curltime initial_tv;
-  int pending_ms;
-#endif
   int r = 0;
 
   if(!timeout_ms)
@@ -94,28 +84,16 @@ int Curl_wait_ms(int timeout_ms)
 #elif defined(USE_WINSOCK)
   Sleep(timeout_ms);
 #else
-  pending_ms = timeout_ms;
-  initial_tv = Curl_now();
-  do {
-    int error;
 #if defined(HAVE_POLL_FINE)
-    r = poll(NULL, 0, pending_ms);
+  r = poll(NULL, 0, timeout_ms);
 #else
-    pending_tv.tv_sec = pending_ms / 1000;
-    pending_tv.tv_usec = (pending_ms % 1000) * 1000;
+  {
+    struct timeval pending_tv;
+    pending_tv.tv_sec = timeout_ms / 1000;
+    pending_tv.tv_usec = (timeout_ms % 1000) * 1000;
     r = select(0, NULL, NULL, NULL, &pending_tv);
+  }
 #endif /* HAVE_POLL_FINE */
-    if(r != -1)
-      break;
-    error = SOCKERRNO;
-    if(error && ERROR_NOT_EINTR(error))
-      break;
-    pending_ms = timeout_ms - ELAPSED_MS();
-    if(pending_ms <= 0) {
-      r = 0;  /* Simulate a "call timed out" case */
-      break;
-    }
-  } while(r == -1);
 #endif /* USE_WINSOCK */
   if(r)
     r = -1;
@@ -158,7 +136,6 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
   fd_set fds_err;
   curl_socket_t maxfd;
 #endif
-  struct curltime initial_tv = {0, 0};
   int pending_ms = 0;
   int r;
   int ret;
@@ -183,7 +160,6 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
 
   if(timeout_ms > 0) {
     pending_ms = (int)timeout_ms;
-    initial_tv = Curl_now();
   }
 
 #ifdef HAVE_POLL_FINE
@@ -208,26 +184,11 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
     num++;
   }
 
-  do {
-    int error;
-    if(timeout_ms < 0)
-      pending_ms = -1;
-    else if(!timeout_ms)
-      pending_ms = 0;
-    r = poll(pfd, num, pending_ms);
-    if(r != -1)
-      break;
-    error = SOCKERRNO;
-    if(error && ERROR_NOT_EINTR(error))
-      break;
-    if(timeout_ms > 0) {
-      pending_ms = (int)(timeout_ms - ELAPSED_MS());
-      if(pending_ms <= 0) {
-        r = 0;  /* Simulate a "call timed out" case */
-        break;
-      }
-    }
-  } while(r == -1);
+  if(timeout_ms < 0)
+    pending_ms = -1;
+  else if(!timeout_ms)
+    pending_ms = 0;
+  r = poll(pfd, num, pending_ms);
 
   if(r < 0)
     return -1;
@@ -290,61 +251,45 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
 
   ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
 
-  do {
-    int error;
-    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;
-    }
+  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:
+  /* 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.
+     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
-       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.
+     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.
+     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).
-    */
+     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);
+  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);
+  r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
 #endif
 
-    if(r != -1)
-      break;
-    error = SOCKERRNO;
-    if(error && ERROR_NOT_EINTR(error))
-      break;
-    if(timeout_ms > 0) {
-      pending_ms = (int)(timeout_ms - ELAPSED_MS());
-      if(pending_ms <= 0) {
-        r = 0;  /* Simulate a "call timed out" case */
-        break;
-      }
-    }
-  } while(r == -1);
-
   if(r < 0)
     return -1;
   if(r == 0)
@@ -399,7 +344,6 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
   fd_set fds_err;
   curl_socket_t maxfd;
 #endif
-  struct curltime initial_tv = {0, 0};
   bool fds_none = TRUE;
   unsigned int i;
   int pending_ms = 0;
@@ -425,31 +369,15 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
 
   if(timeout_ms > 0) {
     pending_ms = timeout_ms;
-    initial_tv = Curl_now();
   }
 
 #ifdef HAVE_POLL_FINE
 
-  do {
-    int error;
-    if(timeout_ms < 0)
-      pending_ms = -1;
-    else if(!timeout_ms)
-      pending_ms = 0;
-    r = poll(ufds, nfds, pending_ms);
-    if(r != -1)
-      break;
-    error = SOCKERRNO;
-    if(error && ERROR_NOT_EINTR(error))
-      break;
-    if(timeout_ms > 0) {
-      pending_ms = (int)(timeout_ms - ELAPSED_MS());
-      if(pending_ms <= 0) {
-        r = 0;  /* Simulate a "call timed out" case */
-        break;
-      }
-    }
-  } while(r == -1);
+  if(timeout_ms < 0)
+    pending_ms = -1;
+  else if(!timeout_ms)
+    pending_ms = 0;
+  r = poll(ufds, nfds, pending_ms);
 
   if(r < 0)
     return -1;
@@ -502,42 +430,27 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
 
   ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
 
-  do {
-    int error;
-    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;
-    }
+  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);
+  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);
+  r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
 #endif
-    if(r != -1)
-      break;
-    error = SOCKERRNO;
-    if(error && ERROR_NOT_EINTR(error))
-      break;
-    if(timeout_ms > 0) {
-      pending_ms = timeout_ms - ELAPSED_MS();
-      if(pending_ms <= 0) {
-        r = 0;  /* Simulate a "call timed out" case */
-        break;
-      }
-    }
-  } while(r == -1);
 
   if(r < 0)
     return -1;

+ 1 - 9
lib/select.h

@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -75,20 +75,12 @@ struct pollfd
 int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
                       curl_socket_t writefd,
                       time_t timeout_ms);
-
 #define SOCKET_READABLE(x,z) \
   Curl_socket_check(x, CURL_SOCKET_BAD, CURL_SOCKET_BAD, (time_t)z)
 #define SOCKET_WRITABLE(x,z) \
   Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, x, (time_t)z)
 
 int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
-
-/* On non-DOS and non-Winsock platforms, when Curl_ack_eintr is set,
- * EINTR condition is honored and function might exit early without
- * awaiting full timeout.  Otherwise EINTR will be ignored and full
- * timeout will elapse. */
-extern int Curl_ack_eintr;
-
 int Curl_wait_ms(int timeout_ms);
 
 #ifdef TPF

+ 1 - 1
lib/sendf.c

@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms