static int redisContextWaitReady(redisContext *c, long msec) { struct pollfd wfd[1]; wfd[0].fd = c->fd; wfd[0].events = POLLOUT; if (errno == EINPROGRESS) { int res; if ((res = poll(wfd, 1, msec)) == -1) { __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)"); redisContextCloseFd(c); return REDIS_ERR; } else if (res == 0) { errno = ETIMEDOUT; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; } if (redisCheckSocketError(c) != REDIS_OK) return REDIS_ERR; return REDIS_OK; } __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; }
static int redisSetBlocking(redisContext *c, int blocking) { #ifdef FASTOREDIS #ifdef OS_WIN unsigned long flags = blocking; int res = ioctlsocket(c->fd, FIONBIO, &flags); if (res == SOCKET_ERROR) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,"ioctlsocket(FIONBIO)"); redisContextCloseFd(c); return REDIS_ERR; } #else int flags; /* Set the socket nonblocking. * Note that fcntl(2) for F_GETFL and F_SETFL can't be * interrupted by a signal. */ if ((flags = fcntl(c->fd, F_GETFL)) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)"); redisContextCloseFd(c); return REDIS_ERR; } if (blocking) flags &= ~O_NONBLOCK; else flags |= O_NONBLOCK; if (fcntl(c->fd, F_SETFL, flags) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)"); redisContextCloseFd(c); return REDIS_ERR; } #endif #else int flags; /* Set the socket nonblocking. * Note that fcntl(2) for F_GETFL and F_SETFL can't be * interrupted by a signal. */ if ((flags = fcntl(c->fd, F_GETFL)) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)"); redisContextCloseFd(c); return REDIS_ERR; } if (blocking) flags &= ~O_NONBLOCK; else flags |= O_NONBLOCK; if (fcntl(c->fd, F_SETFL, flags) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)"); redisContextCloseFd(c); return REDIS_ERR; } #endif return REDIS_OK; }
int redisContextSetTimeout(redisContext *c, const struct timeval tv) { if (setsockopt(c->fd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv)) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_RCVTIMEO)"); return REDIS_ERR; } if (setsockopt(c->fd,SOL_SOCKET,SO_SNDTIMEO,&tv,sizeof(tv)) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_SNDTIMEO)"); return REDIS_ERR; } return REDIS_OK; }
static int redisContextWaitReady(redisContext *c, const struct timeval *timeout) { struct pollfd wfd[1]; long msec; msec = -1; wfd[0].fd = c->fd; wfd[0].events = POLLOUT; /* Only use timeout when not NULL. */ if (timeout != NULL) { if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) { __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL); redisContextCloseFd(c); 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) { int res; if ((res = poll(wfd, 1, msec)) == -1) { __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)"); redisContextCloseFd(c); return REDIS_ERR; } else if (res == 0) { errno = ETIMEDOUT; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; } if (redisCheckSocketError(c) != REDIS_OK) return REDIS_ERR; return REDIS_OK; } __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; }
int redisCheckSocketError(redisContext *c) { int err = 0; socklen_t errlen = sizeof(err); if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)"); return REDIS_ERR; } if (err) { errno = err; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); return REDIS_ERR; } return REDIS_OK; }
static int redisCreateSocket(redisContext *c, int type) { int s, on = 1; if ((s = socket(type, SOCK_STREAM, 0)) == -1) { SETERRNO; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); return REDIS_ERR; } if (type == AF_INET) { if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) == -1) { SETERRNO; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); close(s); return REDIS_ERR; } } return s; }
static int redisSetTcpNoDelay(redisContext *c) { int yes = 1; if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)"); redisContextCloseFd(c); return REDIS_ERR; } return REDIS_OK; }
static int redisSetReuseAddr(redisContext *c) { int on = 1; if (setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; } return REDIS_OK; }
static int redisSetBlocking(redisContext *c, int fd, int blocking) { #ifdef HIREDIS_WIN int iResult; int flag; if (blocking) flag = 0; else flag = 1; iResult = ioctlsocket(fd, FIONBIO, &flag); if (iResult != NO_ERROR) { SETERRNO; __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)"); close(fd); return REDIS_ERR; } #else int flags; /* Set the socket nonblocking. * Note that fcntl(2) for F_GETFL and F_SETFL can't be * interrupted by a signal. */ if ((flags = fcntl(fd, F_GETFL)) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)"); close(fd); return REDIS_ERR; } if (blocking) flags &= ~O_NONBLOCK; else flags |= O_NONBLOCK; if (fcntl(fd, F_SETFL, flags) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)"); close(fd); return REDIS_ERR; } #endif return REDIS_OK; }
static int redisSetTcpNoDelay(redisContext *c, int fd) { int yes = 1; if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes)) == -1) { SETERRNO; __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)"); close(fd); return REDIS_ERR; } return REDIS_OK; }
static int redisSetReuseAddr(redisContext *c, int fd) { int on = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) == -1) { SETERRNO; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); close(fd); return REDIS_ERR; } return REDIS_OK; }
static int redisSetTcpNoDelay(redisContext *c) { #if _WIN32 #if 1 BOOL yes = TRUE; if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, (const char*)&yes, sizeof(yes)) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)"); redisContextCloseFd(c); return REDIS_ERR; } #endif #else int yes = 1; if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)"); redisContextCloseFd(c); return REDIS_ERR; } #endif return REDIS_OK; }
static int redisCreateSocket(redisContext *c, int type) { int s; if ((s = socket(type, SOCK_STREAM, 0)) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); return REDIS_ERR; } if (type == AF_INET) { if (redisSetReuseAddr(c,s) == REDIS_ERR) { return REDIS_ERR; } } return s; }
static int redisSetBlocking(redisContext *c, int blocking) { int flags; /* Set the socket nonblocking. * Note that fcntl(2) for F_GETFL and F_SETFL can't be * interrupted by a signal. */ if ((flags = fcntl(c->fd, F_GETFL)) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)"); redisContextCloseFd(c); return REDIS_ERR; } if (blocking) flags &= ~O_NONBLOCK; else flags |= O_NONBLOCK; if (fcntl(c->fd, F_SETFL, flags) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)"); redisContextCloseFd(c); return REDIS_ERR; } return REDIS_OK; }
static int redisContextWaitReady(redisContext *c, int fd, const struct timeval *timeout) { struct timeval to; struct timeval *toptr = NULL; fd_set wfd; /* Only use timeout when not NULL. */ if (timeout != NULL) { to = *timeout; toptr = &to; } #ifdef HIREDIS_WIN if (errno == EINPROGRESS || errno == WSAEWOULDBLOCK) { #else if (errno == EINPROGRESS) { #endif FD_ZERO(&wfd); FD_SET(fd, &wfd); if (select(FD_SETSIZE, NULL, &wfd, NULL, toptr) == -1) { SETERRNO; __redisSetErrorFromErrno(c,REDIS_ERR_IO,"select(2)"); close(fd); return REDIS_ERR; } if (!FD_ISSET(fd, &wfd)) { #ifdef HIREDIS_WIN errno = WSAETIMEDOUT; #else errno = ETIMEDOUT; #endif __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); close(fd); return REDIS_ERR; } return REDIS_OK; } SETERRNO; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); close(fd); return REDIS_ERR; } int redisCheckSocketError(redisContext *c, int fd) { int err = 0; socklen_t errlen = sizeof(err); if (getsockopt(fd, SOL_SOCKET, SO_ERROR,(char*)&err, &errlen) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)"); close(fd); return REDIS_ERR; } if (err) { errno = err; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); close(fd); return REDIS_ERR; } return REDIS_OK; }
static int redisContextWaitReady(redisContext *c, int fd, const struct timeval *timeout) { #ifdef HIREDIS_WIN // Keep using older select mechanism in windows struct timeval to; struct timeval *toptr = NULL; fd_set wfd; /* Only use timeout when not NULL. */ if (timeout != NULL) { to = *timeout; toptr = &to; } if (errno == EINPROGRESS || errno == WSAEWOULDBLOCK) { FD_ZERO(&wfd); FD_SET(fd, &wfd); if (select(FD_SETSIZE, NULL, &wfd, NULL, toptr) == -1) { SETERRNO; __redisSetErrorFromErrno(c,REDIS_ERR_IO,"select(2)"); close(fd); return REDIS_ERR; } if (!FD_ISSET(fd, &wfd)) { errno = WSAETIMEDOUT; __redisSetErrorFromErrno(c,REDIS_ERR_IO,"timed out"); close(fd); return REDIS_ERR; } #else // newer implementation uses poll 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) { 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) { int res; if ((res = poll(wfd, 1, msec)) == -1) { __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)"); close(fd); return REDIS_ERR; } else if (res == 0) { errno = ETIMEDOUT; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); close(fd); return REDIS_ERR; } #endif if (redisCheckSocketError(c, fd) != REDIS_OK) return REDIS_ERR; return REDIS_OK; } SETERRNO; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); close(fd); return REDIS_ERR; } int redisCheckSocketError(redisContext *c, int fd) { int err = 0; socklen_t errlen = sizeof(err); if (getsockopt(fd, SOL_SOCKET, SO_ERROR,(char*)&err, &errlen) == -1) { SETERRNO; __redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)"); close(fd); return REDIS_ERR; } if (err) { errno = err; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); close(fd); return REDIS_ERR; } return REDIS_OK; }
static int redisContextWaitReady(redisContext *c, long msec) { #ifdef FASTO #ifdef OS_WIN fd_set master_set; FD_ZERO(&master_set); int max_sd = c->fd; FD_SET(c->fd, &master_set); struct timeval tv; tv.tv_sec = msec/1000; tv.tv_usec = (msec % 1000) * 1000; if (errno == EINPROGRESS) { int res; if ((res = select(max_sd + 1, &master_set, NULL, NULL, &tv)) == -1) { __redisSetErrorFromErrno(c, REDIS_ERR_IO, "select(2)"); redisContextCloseFd(c); return REDIS_ERR; } else if (res == 0) { errno = ETIMEDOUT; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; } if (redisCheckSocketError(c) != REDIS_OK) return REDIS_ERR; return REDIS_OK; } __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; #else struct pollfd wfd[1]; wfd[0].fd = c->fd; wfd[0].events = POLLOUT; if (errno == EINPROGRESS) { int res; if ((res = poll(wfd, 1, msec)) == -1) { __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)"); redisContextCloseFd(c); return REDIS_ERR; } else if (res == 0) { errno = ETIMEDOUT; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; } if (redisCheckSocketError(c) != REDIS_OK) return REDIS_ERR; return REDIS_OK; } __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; #endif #else struct pollfd wfd[1]; wfd[0].fd = c->fd; wfd[0].events = POLLOUT; if (errno == EINPROGRESS) { int res; if ((res = poll(wfd, 1, msec)) == -1) { __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)"); redisContextCloseFd(c); return REDIS_ERR; } else if (res == 0) { errno = ETIMEDOUT; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; } if (redisCheckSocketError(c) != REDIS_OK) return REDIS_ERR; return REDIS_OK; } __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; #endif }
static int redisContextWaitReady(redisContext *c, const struct timeval *timeout) { long msec; /* msec = -1; */ msec = 15000; // 15 seconds /* Only use timeout when not NULL. */ if (timeout != NULL) { if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) { __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL); redisContextCloseFd(c->fd); return REDIS_ERR; } msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000); if (msec < 0 || msec > INT_MAX) { msec = INT_MAX; } } #ifdef _WIN32 fd_set wfd; struct timeval toptr = {15, 0}; if (timeout != NULL) { toptr.tv_sec = timeout->tv_sec; toptr.tv_usec = timeout->tv_usec; } if (errno == EINPROGRESS || errno == WSAEWOULDBLOCK) { FD_ZERO(&wfd); FD_SET(c->fd, &wfd); if (select(FD_SETSIZE, NULL, &wfd, NULL, &toptr) == -1) { SETERRNO; __redisSetErrorFromErrno(c,REDIS_ERR_IO,"select(2)"); redisContextCloseFd(c->fd); return REDIS_ERR; } if (!FD_ISSET(c->fd, &wfd)) { #ifdef _WIN32 errno = WSAETIMEDOUT; #else errno = ETIMEDOUT; #endif __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); close(c->fd); return REDIS_ERR; } if (redisCheckSocketError(c) != REDIS_OK) return REDIS_ERR; return REDIS_OK; } #else struct pollfd wfd[1]; if (errno == EINPROGRESS) { int res; wfd[0].fd = c->fd; wfd[0].events = POLLOUT; if ((res = poll(wfd, 1, msec)) == -1) { __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)"); redisContextCloseFd(c); return REDIS_ERR; } else if (res == 0) { errno = ETIMEDOUT; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; } if (redisCheckSocketError(c) != REDIS_OK) return REDIS_ERR; return REDIS_OK; } #endif __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; }
static int redisContextWaitReady(redisContext *c, const struct timeval *timeout) { #ifdef FASTOREDIS #ifdef OS_WIN fd_set master_set; FD_ZERO(&master_set); int max_sd = c->fd; FD_SET(c->fd, &master_set); struct timeval tm; tm.tv_sec = 60; tm.tv_usec = 0; /* Only use timeout when not NULL. */ if (timeout != NULL) { if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) { redisContextCloseFd(c); return REDIS_ERR; } tm = *timeout; } if (errno == EINPROGRESS) { int res; if ((res = select(max_sd + 1, &master_set, NULL, NULL, &tm)) == -1) { __redisSetErrorFromErrno(c, REDIS_ERR_IO, "select(2)"); redisContextCloseFd(c); return REDIS_ERR; } else if (res == 0) { errno = ETIMEDOUT; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; } if (redisCheckSocketError(c) != REDIS_OK) return REDIS_ERR; return REDIS_OK; } __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; #else struct pollfd wfd[1]; long msec; msec = -1; wfd[0].fd = c->fd; wfd[0].events = POLLOUT; /* Only use timeout when not NULL. */ if (timeout != NULL) { if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) { __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL); redisContextCloseFd(c); 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) { int res; if ((res = poll(wfd, 1, msec)) == -1) { __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)"); redisContextCloseFd(c); return REDIS_ERR; } else if (res == 0) { errno = ETIMEDOUT; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; } if (redisCheckSocketError(c) != REDIS_OK) return REDIS_ERR; return REDIS_OK; } __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; #endif #else struct pollfd wfd[1]; long msec; msec = -1; wfd[0].fd = c->fd; wfd[0].events = POLLOUT; /* Only use timeout when not NULL. */ if (timeout != NULL) { if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) { __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL); redisContextCloseFd(c); 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) { int res; if ((res = poll(wfd, 1, msec)) == -1) { __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)"); redisContextCloseFd(c); return REDIS_ERR; } else if (res == 0) { errno = ETIMEDOUT; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; } if (redisCheckSocketError(c) != REDIS_OK) return REDIS_ERR; return REDIS_OK; } __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); redisContextCloseFd(c); return REDIS_ERR; #endif }