diff options
-rw-r--r-- | fmacros.h | 4 | ||||
-rw-r--r-- | hiredis.c | 7 | ||||
-rw-r--r-- | hiredis.h | 3 | ||||
-rw-r--r-- | net.c | 39 | ||||
-rw-r--r-- | net.h | 1 |
5 files changed, 54 insertions, 0 deletions
@@ -13,4 +13,8 @@ #define _XOPEN_SOURCE #endif +#if __APPLE__ && __MACH__ +#define _OSX +#endif + #endif @@ -1092,6 +1092,13 @@ int redisSetTimeout(redisContext *c, struct timeval tv) { return REDIS_ERR; } +/* Enable connection KeepAlive. */ +int redisEnableKeepAlive(redisContext *c) { + if (redisKeepAlive(c, REDIS_KEEPALIVE_INTERVAL) != REDIS_OK) + return REDIS_ERR; + return REDIS_OK; +} + /* Use this function to handle a read event on the descriptor. It will try * and read some bytes from the socket and feed them to the reply parser. * @@ -88,6 +88,8 @@ #define REDIS_READER_MAX_BUF (1024*16) /* Default max unused reader buffer. */ +#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */ + #ifdef __cplusplus extern "C" { #endif @@ -177,6 +179,7 @@ redisContext *redisConnectUnix(const char *path); redisContext *redisConnectUnixWithTimeout(const char *path, struct timeval tv); redisContext *redisConnectUnixNonBlock(const char *path); int redisSetTimeout(redisContext *c, struct timeval tv); +int redisEnableKeepAlive(redisContext *c); void redisFree(redisContext *c); int redisBufferRead(redisContext *c); int redisBufferWrite(redisContext *c, int *done); @@ -113,6 +113,45 @@ static int redisSetBlocking(redisContext *c, int fd, int blocking) { return REDIS_OK; } +int redisKeepAlive(redisContext *c, int interval) { + int val = 1; + int fd = c->fd; + + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1){ + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } + +#ifdef _OSX + val = interval; + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &val, sizeof(val)) < 0) { + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } +#else + val = interval; + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) { + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } + + val = interval/3; + if (val == 0) val = 1; + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0) { + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } + + val = 3; + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) { + __redisSetError(c,REDIS_ERR_OTHER,strerror(errno)); + return REDIS_ERR; + } +#endif + + return REDIS_OK; +} + static int redisSetTcpNoDelay(redisContext *c, int fd) { int yes = 1; if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) { @@ -43,5 +43,6 @@ int redisCheckSocketError(redisContext *c, int fd); int redisContextSetTimeout(redisContext *c, struct timeval tv); int redisContextConnectTcp(redisContext *c, const char *addr, int port, struct timeval *timeout); int redisContextConnectUnix(redisContext *c, const char *path, struct timeval *timeout); +int redisKeepAlive(redisContext *c, int interval); #endif |