Commit 2b61fd1a authored by Pieter Noordhuis's avatar Pieter Noordhuis
Browse files

Replace select(2) with poll(2)

Like f8debbfd.
parent 1f6a4d8c
...@@ -7,10 +7,8 @@ ...@@ -7,10 +7,8 @@
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
/* select */ /* poll */
#include <sys/select.h> #include <poll.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h> #include <unistd.h>
/* local */ /* local */
...@@ -124,51 +122,64 @@ int redis_handle_connect_gai(redis_handle *h, ...@@ -124,51 +122,64 @@ int redis_handle_connect_gai(redis_handle *h,
return redis__finish_connect(h, fd); return redis__finish_connect(h, fd);
} }
static int redis__select(int mode, int fd, struct timeval timeout) { static int redis__poll(int mode, int fd, struct timeval timeout) {
fd_set rfd, wfd; struct pollfd pfd;
fd_set *_set = NULL, *_rfd = NULL, *_wfd = NULL; int msec;
int so_error; int rv;
assert(fd < FD_SETSIZE); pfd.fd = fd;
pfd.events = 0;
switch(mode) { pfd.revents = 0;
case REDIS__READABLE:
FD_ZERO(&rfd); if (mode & REDIS__READABLE) {
FD_SET(fd, &rfd); pfd.events |= POLLIN;
_rfd = _set = &rfd; }
break;
case REDIS__WRITABLE: if (mode & REDIS__WRITABLE) {
FD_ZERO(&wfd); pfd.events |= POLLOUT;
FD_SET(fd, &wfd); }
_wfd = _set = &wfd;
break; msec = (timeout.tv_sec * 1000) + ((timeout.tv_usec + 999) / 1000);
default: if (msec < 0) {
assert(NULL && "invalid mode"); msec = 0;
} }
if (select(FD_SETSIZE, _rfd, _wfd, NULL, &timeout) == -1) { rv = poll(&pfd, 1, msec);
if (rv == -1) {
return REDIS_ESYS; return REDIS_ESYS;
} }
/* Not in set means select(2) timed out */ /* No events means poll(2) timed out */
if (!FD_ISSET(fd, _set)) { if (rv == 0) {
errno = ETIMEDOUT; errno = ETIMEDOUT;
return REDIS_ESYS; return REDIS_ESYS;
} }
/* Check for socket error */ /* POLLERR is always bad */
so_error = redis_fd_error(fd); if (pfd.revents & POLLERR) {
if (so_error < 0) { goto error;
return so_error;
} }
if (so_error) { /* POLLHUP is only bad when interested in POLLOUT.
/* Act as if the socket error occured with select(2). */ * When interested in POLLIN, reads can continue until EOF. */
errno = so_error; if ((pfd.revents & POLLHUP) && (pfd.events & POLLOUT)) {
return REDIS_ESYS; goto error;
} }
return REDIS_OK; return REDIS_OK;
error:
rv = redis_fd_error(fd);
if (rv < 0) {
return rv;
}
/* We got POLLERR so the socket error MUST be non-zero */
assert(rv && "Expected socket error");
/* Act as if the socket error occured */
errno = rv;
return REDIS_ESYS;
} }
static int redis__wait(redis_handle *h, int mode) { static int redis__wait(redis_handle *h, int mode) {
...@@ -179,7 +190,7 @@ static int redis__wait(redis_handle *h, int mode) { ...@@ -179,7 +190,7 @@ static int redis__wait(redis_handle *h, int mode) {
return REDIS_ESYS; return REDIS_ESYS;
} }
rv = redis__select(mode, h->fd, h->timeout); rv = redis__poll(mode, h->fd, h->timeout);
if (rv < 0) { if (rv < 0) {
return REDIS_ESYS; return REDIS_ESYS;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment