# HG changeset patch # User Paolo Bonzini # Date 1218011273 -7200 # Node ID c3ecbe083a26c676995a5fef11df332b82d92f03 # Parent 38eff58347bb64823236f2cdf046911ea0f53357 microoptimization of lib/poll.c 2008-08-06 Paolo Bonzini * lib/poll.c (poll): Avoid division when timeout is 0, cache _SC_OPEN_MAX, avoid repeated access to errno. Check for nfd < 0. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-08-06 Paolo Bonzini + + * lib/poll.c (poll): Avoid division when timeout is 0, cache + _SC_OPEN_MAX, avoid repeated access to errno. Check for nfd < 0. + 2008-08-06 Jim Meyering * modules/inet_pton (License): Relicense under LGPLv2+. diff --git a/lib/poll.c b/lib/poll.c --- a/lib/poll.c +++ b/lib/poll.c @@ -55,19 +55,25 @@ int timeout; { fd_set rfds, wfds, efds; - struct timeval tv, *ptv; + struct timeval tv = { 0, 0 }; + struct timeval *ptv; int maxfd, rc; nfds_t i; #ifdef _SC_OPEN_MAX - if (nfd > sysconf (_SC_OPEN_MAX)) + static int sc_open_max = -1; + + if (nfd < 0 + || (nfd > sc_open_max + && (sc_open_max != -1 + || nfd > (sc_open_max = sysconf (_SC_OPEN_MAX))))) { errno = EINVAL; return -1; } #else /* !_SC_OPEN_MAX */ #ifdef OPEN_MAX - if (nfd > OPEN_MAX) + if (nfd < 0 || nfd > OPEN_MAX) { errno = EINVAL; return -1; @@ -84,10 +90,11 @@ } /* convert timeout number into a timeval structure */ - ptv = &tv; - if (timeout >= 0) + if (timeout == 0) + ptv = &tv; + else if (timeout > 0) { - /* return immediately or after timeout */ + ptv = &tv; ptv->tv_sec = timeout / 1000; ptv->tv_usec = (timeout % 1000) * 1000; } @@ -155,6 +162,7 @@ if (FD_ISSET (pfd[i].fd, &rfds)) { int r; + int socket_errno; #if defined __MACH__ && defined __APPLE__ /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK @@ -162,23 +170,25 @@ connected socket, a server socket, or something else using a 0-byte recv, and use ioctl(2) to detect POLLHUP. */ r = recv (pfd[i].fd, NULL, 0, MSG_PEEK); - if (r == 0 || errno == ENOTSOCK) + socket_errno = (r < 0) ? errno : 0; + if (r == 0 || socket_errno == ENOTSOCK) ioctl(pfd[i].fd, FIONREAD, &r); #else char data[64]; r = recv (pfd[i].fd, data, sizeof (data), MSG_PEEK); + socket_errno = (r < 0) ? errno : 0; #endif if (r == 0) happened |= POLLHUP; /* If the event happened on an unconnected server socket, that's fine. */ - else if (r > 0 || ( /* (r == -1) && */ errno == ENOTCONN)) + else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN)) happened |= (POLLIN | POLLRDNORM) & sought; /* Distinguish hung-up sockets from other errors. */ - else if (errno == ESHUTDOWN || errno == ECONNRESET - || errno == ECONNABORTED || errno == ENETRESET) + else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET + || socket_errno == ECONNABORTED || socket_errno == ENETRESET) happened |= POLLHUP; else