From owner-svn-src-head@FreeBSD.ORG Mon Apr 30 12:11:45 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EDCD81065673; Mon, 30 Apr 2012 12:11:45 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id BEF968FC1A; Mon, 30 Apr 2012 12:11:45 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q3UCBjnb065201; Mon, 30 Apr 2012 12:11:45 GMT (envelope-from des@svn.freebsd.org) Received: (from des@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q3UCBjna065199; Mon, 30 Apr 2012 12:11:45 GMT (envelope-from des@svn.freebsd.org) Message-Id: <201204301211.q3UCBjna065199@svn.freebsd.org> From: Dag-Erling Smorgrav Date: Mon, 30 Apr 2012 12:11:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r234837 - head/lib/libfetch X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 30 Apr 2012 12:11:46 -0000 Author: des Date: Mon Apr 30 12:11:45 2012 New Revision: 234837 URL: http://svn.freebsd.org/changeset/base/234837 Log: Since the socket is non-blocking, it is necessary to use select(2) even when there is no timeout, because read(2) will return immediately if there is no data waiting in the TCP buffer, causing fetch_read() to busy-loop on slow connections. MFC after: 3 weeks Noticed by: Yanhui Shen Modified: head/lib/libfetch/common.c Modified: head/lib/libfetch/common.c ============================================================================== --- head/lib/libfetch/common.c Mon Apr 30 11:28:17 2012 (r234836) +++ head/lib/libfetch/common.c Mon Apr 30 12:11:45 2012 (r234837) @@ -455,11 +455,9 @@ fetch_read(conn_t *conn, char *buf, size struct timeval now, timeout, delta; fd_set readfds; ssize_t rlen, total; - int r; char *start; - if (fetchTimeout) { - FD_ZERO(&readfds); + if (fetchTimeout > 0) { gettimeofday(&timeout, NULL); timeout.tv_sec += fetchTimeout; } @@ -523,23 +521,21 @@ fetch_read(conn_t *conn, char *buf, size return (-1); } // assert(rlen == FETCH_READ_WAIT); - while (fetchTimeout && !FD_ISSET(conn->sd, &readfds)) { + FD_ZERO(&readfds); + while (!FD_ISSET(conn->sd, &readfds)) { FD_SET(conn->sd, &readfds); - gettimeofday(&now, NULL); - delta.tv_sec = timeout.tv_sec - now.tv_sec; - delta.tv_usec = timeout.tv_usec - now.tv_usec; - if (delta.tv_usec < 0) { - delta.tv_usec += 1000000; - delta.tv_sec--; - } - if (delta.tv_sec < 0) { - errno = ETIMEDOUT; - fetch_syserr(); - return (-1); + if (fetchTimeout > 0) { + gettimeofday(&now, NULL); + if (!timercmp(&timeout, &now, >)) { + errno = ETIMEDOUT; + fetch_syserr(); + return (-1); + } + timersub(&timeout, &now, &delta); } errno = 0; - r = select(conn->sd + 1, &readfds, NULL, NULL, &delta); - if (r == -1) { + if (select(conn->sd + 1, &readfds, NULL, NULL, + fetchTimeout > 0 ? &delta : NULL) < 0) { if (errno == EINTR) { if (fetchRestartCalls) continue;