Index: curl/lib/select.c =================================================================== RCS file: /cvsroot/curl/curl/lib/select.c,v retrieving revision 1.41 diff -u -r1.41 select.c --- curl/lib/select.c 16 Apr 2007 16:34:08 -0000 1.41 +++ curl/lib/select.c 19 Apr 2007 16:12:41 -0000 @@ -76,9 +76,9 @@ #define elapsed_ms (int)curlx_tvdiff(curlx_tvnow(), initial_tv) #ifdef CURL_ACKNOWLEDGE_EINTR -#define error_not_EINTR (error != EINTR) +#define error_is_EINTR (error == EINTR) #else -#define error_not_EINTR (1) +#define error_is_EINTR (0) #endif #define SMALL_POLLNFDS 0X20 @@ -136,9 +136,15 @@ pending_tv.tv_usec = (pending_ms % 1000) * 1000; r = select(0, NULL, NULL, NULL, &pending_tv); #endif /* HAVE_POLL_FINE */ - } while ((r == -1) && (error = SOCKERRNO) && - (error != EINVAL) && error_not_EINTR && - ((pending_ms = timeout_ms - elapsed_ms) > 0)); + if (r != -1) + break; + error = SOCKERRNO; + if ((error == EINVAL) || error_is_EINTR) + break; + pending_ms = timeout_ms - elapsed_ms; + if (pending_ms <= 0) + break; + } while (r == -1); #endif /* USE_WINSOCK */ if (r) r = -1; @@ -187,8 +193,14 @@ return r; } - pending_ms = timeout_ms; - initial_tv = curlx_tvnow(); + /* Avoid initial timestamp, avoid gettimeofday() call, when elapsed time in + this function does not need to be measured. This happens when function is + called with a zero timeout or a timeout indicating a blocking call. */ + + if (timeout_ms > 0) { + pending_ms = timeout_ms; + initial_tv = curlx_tvnow(); + } #ifdef HAVE_POLL_FINE @@ -209,10 +221,20 @@ do { if (timeout_ms < 0) pending_ms = -1; + else if (!timeout_ms) + pending_ms = 0; r = poll(pfd, num, pending_ms); - } while ((r == -1) && (error = SOCKERRNO) && - (error != EINVAL) && error_not_EINTR && - ((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0))); + if (r != -1) + break; + error = SOCKERRNO; + if ((error == EINVAL) || error_is_EINTR) + break; + if (timeout_ms > 0) { + pending_ms = timeout_ms - elapsed_ms; + if (pending_ms <= 0) + break; + } + } while (r == -1); if (r < 0) return -1; @@ -262,14 +284,26 @@ ptimeout = (timeout_ms < 0) ? NULL : &pending_tv; do { - if (ptimeout) { + 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; + } r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout); - } while ((r == -1) && (error = SOCKERRNO) && - (error != EINVAL) && (error != EBADF) && error_not_EINTR && - ((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0))); + if (r != -1) + break; + error = SOCKERRNO; + if ((error == EINVAL) || (error == EBADF) || error_is_EINTR) + break; + if (timeout_ms > 0) { + pending_ms = timeout_ms - elapsed_ms; + if (pending_ms <= 0) + break; + } + } while (r == -1); if (r < 0) return -1; @@ -342,18 +376,34 @@ return r; } - pending_ms = timeout_ms; - initial_tv = curlx_tvnow(); + /* Avoid initial timestamp, avoid gettimeofday() call, when elapsed time in + this function does not need to be measured. This happens when function is + called with a zero timeout or a timeout indicating a blocking call. */ + + if (timeout_ms > 0) { + pending_ms = timeout_ms; + initial_tv = curlx_tvnow(); + } #ifdef HAVE_POLL_FINE do { if (timeout_ms < 0) pending_ms = -1; + else if (!timeout_ms) + pending_ms = 0; r = poll(ufds, nfds, pending_ms); - } while ((r == -1) && (error = SOCKERRNO) && - (error != EINVAL) && error_not_EINTR && - ((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0))); + if (r != -1) + break; + error = SOCKERRNO; + if ((error == EINVAL) || error_is_EINTR) + break; + if (timeout_ms > 0) { + pending_ms = timeout_ms - elapsed_ms; + if (pending_ms <= 0) + break; + } + } while (r == -1); #else /* HAVE_POLL_FINE */ @@ -383,14 +433,26 @@ ptimeout = (timeout_ms < 0) ? NULL : &pending_tv; do { - if (ptimeout) { + 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; + } r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout); - } while ((r == -1) && (error = SOCKERRNO) && - (error != EINVAL) && (error != EBADF) && error_not_EINTR && - ((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0))); + if (r != -1) + break; + error = SOCKERRNO; + if ((error == EINVAL) || (error == EBADF) || error_is_EINTR) + break; + if (timeout_ms > 0) { + pending_ms = timeout_ms - elapsed_ms; + if (pending_ms <= 0) + break; + } + } while (r == -1); if (r < 0) return -1; @@ -479,8 +541,14 @@ return r; } - pending_ms = timeout_ms; - initial_tv = curlx_tvnow(); + /* Avoid initial timestamp, avoid gettimeofday() call, when elapsed time in + this function does not need to be measured. This happens when function is + called with a zero timeout or a timeout indicating a blocking call. */ + + if (timeout_ms > 0) { + pending_ms = timeout_ms; + initial_tv = curlx_tvnow(); + } #ifdef HAVE_POLL_FINE @@ -528,10 +596,20 @@ do { if (timeout_ms < 0) pending_ms = -1; + else if (!timeout_ms) + pending_ms = 0; r = poll(poll_fds, poll_nfds, pending_ms); - } while ((r == -1) && (error = SOCKERRNO) && - (error != EINVAL) && error_not_EINTR && - ((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0))); + if (r != -1) + break; + error = SOCKERRNO; + if ((error == EINVAL) || error_is_EINTR) + break; + if (timeout_ms > 0) { + pending_ms = timeout_ms - elapsed_ms; + if (pending_ms <= 0) + break; + } + } while (r == -1); if (r < 0) ret = -1; @@ -581,14 +659,26 @@ ptimeout = (timeout_ms < 0) ? NULL : &pending_tv; do { - if (ptimeout) { + 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; + } r = select(nfds, fds_read, fds_write, fds_excep, ptimeout); - } while ((r == -1) && (error = SOCKERRNO) && - (error != EINVAL) && (error != EBADF) && error_not_EINTR && - ((timeout_ms < 0) || ((pending_ms = timeout_ms - elapsed_ms) > 0))); + if (r != -1) + break; + error = SOCKERRNO; + if ((error == EINVAL) || (error == EBADF) || error_is_EINTR) + break; + if (timeout_ms > 0) { + pending_ms = timeout_ms - elapsed_ms; + if (pending_ms <= 0) + break; + } + } while (r == -1); if (r < 0) ret = -1;