From 5eb6958870b71d30e3ed63e65e9f1d546dc419ec Mon Sep 17 00:00:00 2001 From: Mark Nunberg Date: Thu, 21 Feb 2019 11:49:25 -0500 Subject: [PATCH] Allow option for async connections to not automatically free --- async.c | 7 ++++++- hiredis.c | 3 +++ hiredis.h | 12 ++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/async.c b/async.c index 0ed973e..0a2659c 100644 --- a/async.c +++ b/async.c @@ -361,7 +361,9 @@ static void __redisAsyncDisconnect(redisAsyncContext *ac) { /* For non-clean disconnects, __redisAsyncFree() will execute pending * callbacks with a NULL-reply. */ - __redisAsyncFree(ac); + if (!(c->flags & REDIS_NO_AUTO_FREE)) { + __redisAsyncFree(ac); + } } /* Tries to do a clean disconnect from Redis, meaning it stops new commands @@ -373,6 +375,9 @@ static void __redisAsyncDisconnect(redisAsyncContext *ac) { void redisAsyncDisconnect(redisAsyncContext *ac) { redisContext *c = &(ac->c); c->flags |= REDIS_DISCONNECTING; + + /** unset the auto-free flag here, because disconnect undoes this */ + c->flags &= ~REDIS_NO_AUTO_FREE; if (!(c->flags & REDIS_IN_CALLBACK) && ac->replies.head == NULL) __redisAsyncDisconnect(ac); } diff --git a/hiredis.c b/hiredis.c index ba8d316..2506d51 100644 --- a/hiredis.c +++ b/hiredis.c @@ -668,6 +668,9 @@ redisContext *redisConnectWithOptions(const redisOptions *options) { if (options->options & REDIS_OPT_REUSEADDR) { c->flags |= REDIS_REUSEADDR; } + if (options->options & REDIS_OPT_NOAUTOFREE) { + c->flags |= REDIS_NO_AUTO_FREE; + } if (options->type == REDIS_CONN_TCP) { redisContextConnectBindTcp(c, options->endpoint.tcp.ip, diff --git a/hiredis.h b/hiredis.h index 0d646f8..4025869 100644 --- a/hiredis.h +++ b/hiredis.h @@ -77,6 +77,12 @@ /* Flag that is set when this connection is done through SSL */ #define REDIS_SSL 0x100 +/** + * Flag that indicates the user does not want the context to + * be automatically freed upon error + */ +#define REDIS_NO_AUTO_FREE 0x200 + #define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */ /* number of times we retry to connect in the case of EADDRNOTAVAIL and @@ -121,6 +127,12 @@ struct redisSsl; #define REDIS_OPT_NONBLOCK 0x01 #define REDIS_OPT_REUSEADDR 0x02 +/** + * Don't automatically free the async object on a connection failure, + * or other implicit conditions. Only free on an explicit call to disconnect() or free() + */ +#define REDIS_OPT_NOAUTOFREE 0x04 + typedef struct { /* * the type of connection to use. This also indicates which