diff options
author | Alessio M <masariello@gmail.com> | 2020-09-04 09:31:47 +0100 |
---|---|---|
committer | Alessio M <masariello@gmail.com> | 2020-09-04 09:31:47 +0100 |
commit | d7b1d21e807f8a90a086b2ef5cea9b707d4cc858 (patch) | |
tree | 748b00a48a8b625f1dca22ae4cc5721ab7de87c5 /hiredis.c | |
parent | 07c3618ffe7912c2ebc589ea45501c687a19cf2c (diff) | |
parent | fb0e6c0dd9affd5728c6e0a6423f5dcb7b207947 (diff) |
Merge branch 'master' of github.com:redis/hiredis
Diffstat (limited to 'hiredis.c')
-rw-r--r-- | hiredis.c | 79 |
1 files changed, 53 insertions, 26 deletions
@@ -44,8 +44,11 @@ #include "async.h" #include "win32.h" +extern int redisContextUpdateConnectTimeout(redisContext *c, const struct timeval *timeout); +extern int redisContextUpdateCommandTimeout(redisContext *c, const struct timeval *timeout); + static redisContextFuncs redisContextDefaultFuncs = { - .free_privdata = NULL, + .free_privctx = NULL, .async_read = redisAsyncRead, .async_write = redisAsyncWrite, .read = redisNetRead, @@ -685,7 +688,7 @@ static void redisPushAutoFree(void *privdata, void *reply) { freeReplyObject(reply); } -static redisContext *redisContextInit(const redisOptions *options) { +static redisContext *redisContextInit(void) { redisContext *c; c = hi_calloc(1, sizeof(*c)); @@ -694,13 +697,6 @@ static redisContext *redisContextInit(const redisOptions *options) { c->funcs = &redisContextDefaultFuncs; - /* Set any user supplied RESP3 PUSH handler or use freeReplyObject - * as a default unless specifically flagged that we don't want one. */ - if (options->push_cb != NULL) - redisSetPushCallback(c, options->push_cb); - else if (!(options->options & REDIS_OPT_NO_PUSH_AUTOFREE)) - redisSetPushCallback(c, redisPushAutoFree); - c->obuf = sdsempty(); c->reader = redisReaderCreate(); c->fd = REDIS_INVALID_FD; @@ -709,7 +705,7 @@ static redisContext *redisContextInit(const redisOptions *options) { redisFree(c); return NULL; } - (void)options; /* options are used in other functions */ + return c; } @@ -723,11 +719,16 @@ void redisFree(redisContext *c) { hi_free(c->tcp.host); hi_free(c->tcp.source_addr); hi_free(c->unix_sock.path); - hi_free(c->timeout); + hi_free(c->connect_timeout); + hi_free(c->command_timeout); hi_free(c->saddr); - if (c->funcs->free_privdata) { - c->funcs->free_privdata(c->privdata); - } + + if (c->privdata && c->free_privdata) + c->free_privdata(c->privdata); + + if (c->funcs->free_privctx) + c->funcs->free_privctx(c->privctx); + memset(c, 0xff, sizeof(*c)); hi_free(c); } @@ -743,9 +744,9 @@ int redisReconnect(redisContext *c) { c->err = 0; memset(c->errstr, '\0', strlen(c->errstr)); - if (c->privdata && c->funcs->free_privdata) { - c->funcs->free_privdata(c->privdata); - c->privdata = NULL; + if (c->privctx && c->funcs->free_privctx) { + c->funcs->free_privctx(c->privctx); + c->privctx = NULL; } redisNetClose(c); @@ -761,22 +762,28 @@ int redisReconnect(redisContext *c) { return REDIS_ERR; } + int ret = REDIS_ERR; if (c->connection_type == REDIS_CONN_TCP) { - return redisContextConnectBindTcp(c, c->tcp.host, c->tcp.port, - c->timeout, c->tcp.source_addr); + ret = redisContextConnectBindTcp(c, c->tcp.host, c->tcp.port, + c->connect_timeout, c->tcp.source_addr); } else if (c->connection_type == REDIS_CONN_UNIX) { - return redisContextConnectUnix(c, c->unix_sock.path, c->timeout); + ret = redisContextConnectUnix(c, c->unix_sock.path, c->connect_timeout); } else { /* Something bad happened here and shouldn't have. There isn't enough information in the context to reconnect. */ __redisSetError(c,REDIS_ERR_OTHER,"Not enough information to reconnect"); + ret = REDIS_ERR; } - return REDIS_ERR; + if (c->command_timeout != NULL && (c->flags & REDIS_BLOCK) && c->fd != REDIS_INVALID_FD) { + redisContextSetTimeout(c, *c->command_timeout); + } + + return ret; } redisContext *redisConnectWithOptions(const redisOptions *options) { - redisContext *c = redisContextInit(options); + redisContext *c = redisContextInit(); if (c == NULL) { return NULL; } @@ -790,13 +797,29 @@ redisContext *redisConnectWithOptions(const redisOptions *options) { c->flags |= REDIS_NO_AUTO_FREE; } + /* Set any user supplied RESP3 PUSH handler or use freeReplyObject + * as a default unless specifically flagged that we don't want one. */ + if (options->push_cb != NULL) + redisSetPushCallback(c, options->push_cb); + else if (!(options->options & REDIS_OPT_NO_PUSH_AUTOFREE)) + redisSetPushCallback(c, redisPushAutoFree); + + c->privdata = options->privdata; + c->free_privdata = options->free_privdata; + + if (redisContextUpdateConnectTimeout(c, options->connect_timeout) != REDIS_OK || + redisContextUpdateCommandTimeout(c, options->command_timeout) != REDIS_OK) { + __redisSetError(c, REDIS_ERR_OOM, "Out of memory"); + return c; + } + if (options->type == REDIS_CONN_TCP) { redisContextConnectBindTcp(c, options->endpoint.tcp.ip, - options->endpoint.tcp.port, options->timeout, + options->endpoint.tcp.port, options->connect_timeout, options->endpoint.tcp.source_addr); } else if (options->type == REDIS_CONN_UNIX) { redisContextConnectUnix(c, options->endpoint.unix_socket, - options->timeout); + options->connect_timeout); } else if (options->type == REDIS_CONN_USERFD) { c->fd = options->endpoint.fd; c->flags |= REDIS_CONNECTED; @@ -805,6 +828,10 @@ redisContext *redisConnectWithOptions(const redisOptions *options) { return NULL; } + if (options->command_timeout != NULL && (c->flags & REDIS_BLOCK) && c->fd != REDIS_INVALID_FD) { + redisContextSetTimeout(c, *options->command_timeout); + } + return c; } @@ -820,7 +847,7 @@ redisContext *redisConnect(const char *ip, int port) { redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv) { redisOptions options = {0}; REDIS_OPTIONS_SET_TCP(&options, ip, port); - options.timeout = &tv; + options.connect_timeout = &tv; return redisConnectWithOptions(&options); } @@ -858,7 +885,7 @@ redisContext *redisConnectUnix(const char *path) { redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv) { redisOptions options = {0}; REDIS_OPTIONS_SET_UNIX(&options, path); - options.timeout = &tv; + options.connect_timeout = &tv; return redisConnectWithOptions(&options); } |