diff options
author | Mark Ellzey <mark.thomas@mandiant.com> | 2012-02-21 18:20:29 -0500 |
---|---|---|
committer | Pieter Noordhuis <pcnoordhuis@gmail.com> | 2012-04-18 12:18:07 -0700 |
commit | f8debbfdbebb97f5d0ee2218edf1425ac219cff5 (patch) | |
tree | 696e5f587428638b550a15b687a67d58a37dafcf | |
parent | 857b2690afd8d9fbbb3472c948b74dd6cd6e8a95 (diff) | |
download | hiredict-f8debbfdbebb97f5d0ee2218edf1425ac219cff5.tar.xz |
Use poll() instead of select() inside redisContextWaitReady()
The current select() is limiting in instances where the fd num is > FD_SETSIZE.
Since redisContextWaitReady() only processes a single fd, select would still
fail.
For compatibility reasons I have converted select() over to poll(), eliminating
this problem.
-rw-r--r-- | net.c | 36 |
1 files changed, 24 insertions, 12 deletions
@@ -45,6 +45,8 @@ #include <errno.h> #include <stdarg.h> #include <stdio.h> +#include <poll.h> +#include <limits.h> #include "net.h" #include "sds.h" @@ -121,28 +123,38 @@ static int redisSetTcpNoDelay(redisContext *c, int fd) { return REDIS_OK; } +#define __MAX_MSEC (((LONG_MAX) - 999) / 1000) + static int redisContextWaitReady(redisContext *c, int fd, const struct timeval *timeout) { - struct timeval to; - struct timeval *toptr = NULL; - fd_set wfd; + struct pollfd wfd[1]; + long msec; + + msec = -1; + wfd[0].fd = fd; + wfd[0].events = POLLOUT; /* Only use timeout when not NULL. */ if (timeout != NULL) { - to = *timeout; - toptr = &to; + if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) { + close(fd); + return REDIS_ERR; + } + + msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000); + + if (msec < 0 || msec > INT_MAX) { + msec = INT_MAX; + } } if (errno == EINPROGRESS) { - FD_ZERO(&wfd); - FD_SET(fd, &wfd); + int res; - if (select(FD_SETSIZE, NULL, &wfd, NULL, toptr) == -1) { - __redisSetErrorFromErrno(c,REDIS_ERR_IO,"select(2)"); + if ((res = poll(wfd, 1, msec)) == -1) { + __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)"); close(fd); return REDIS_ERR; - } - - if (!FD_ISSET(fd, &wfd)) { + } else if (res == 0) { errno = ETIMEDOUT; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); close(fd); |