From 1ad49feb71418f26aa6114c7a20ce1463beb3ea9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 23 Jan 2020 13:39:27 +0100 Subject: 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 --- docs/libcurl/curl_global_init.3 | 10 +- lib/easy.c | 8 +- lib/select.c | 215 ++++++++++++---------------------------- lib/select.h | 10 +- lib/sendf.c | 2 +- 5 files changed, 78 insertions(+), 167 deletions(-) diff --git a/docs/libcurl/curl_global_init.3 b/docs/libcurl/curl_global_init.3 index 6ba0920c1..d3b3dc96f 100644 --- a/docs/libcurl/curl_global_init.3 +++ b/docs/libcurl/curl_global_init.3 @@ -5,7 +5,7 @@ .\" * | (__| |_| | _ <| |___ .\" * \___|\___/|_| \_\_____| .\" * -.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. +.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, , 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. diff --git a/lib/easy.c b/lib/easy.c index d1b60861f..0ad33c02b 100644 --- a/lib/easy.c +++ b/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; diff --git a/lib/select.c b/lib/select.c index 2de503d37..b372efff1 100644 --- a/lib/select.c +++ b/lib/select.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, , 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; diff --git a/lib/select.h b/lib/select.h index 687ab164c..ec3021aac 100644 --- a/lib/select.h +++ b/lib/select.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, , 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 diff --git a/lib/sendf.c b/lib/sendf.c index 6c38b04b2..62071c4f2 100644 --- a/lib/sendf.c +++ b/lib/sendf.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms -- cgit v1.2.3