diff --git a/hiredis.c b/hiredis.c index 97ef78b..2d897d5 100644 --- a/hiredis.c +++ b/hiredis.c @@ -586,6 +586,13 @@ static redisContext *redisContextInit(redisReplyFunctions *fn) { return c; } +void redisDisconnect(redisContext *c) { + if (c->cbDisconnect != NULL) + c->cbDisconnect(c,c->privdataDisconnect); + close(c->fd); + c->flags &= ~REDIS_CONNECTED; +} + void redisFree(redisContext *c) { if (c->cbFree != NULL) c->cbFree(c,c->privdataFree); @@ -605,6 +612,7 @@ void redisFree(redisContext *c) { redisContext *redisConnect(const char *ip, int port, redisReplyFunctions *fn) { redisContext *c = redisContextInit(fn); c->flags |= REDIS_BLOCK; + c->flags |= REDIS_CONNECTED; redisContextConnect(c,ip,port); return c; } @@ -612,10 +620,17 @@ redisContext *redisConnect(const char *ip, int port, redisReplyFunctions *fn) { redisContext *redisConnectNonBlock(const char *ip, int port, redisReplyFunctions *fn) { redisContext *c = redisContextInit(fn); c->flags &= ~REDIS_BLOCK; + c->flags |= REDIS_CONNECTED; redisContextConnect(c,ip,port); return c; } +/* Register callback that is triggered when redisDisconnect is called. */ +void redisSetDisconnectCallback(redisContext *c, redisContextCallback *fn, void *privdata) { + c->cbDisconnect = fn; + c->privdataDisconnect = privdata; +} + /* Register callback that is triggered when a command is put in the output * buffer when the context is non-blocking. */ void redisSetCommandCallback(redisContext *c, redisContextCallback *fn, void *privdata) { diff --git a/hiredis.h b/hiredis.h index 0dd32bd..6333028 100644 --- a/hiredis.h +++ b/hiredis.h @@ -37,6 +37,10 @@ * least significant bit of the flags field in redisContext. */ #define REDIS_BLOCK 0x1 +/* Connection may be disconnected before being free'd. The second bit + * in the flags field is set when the context is connected. */ +#define REDIS_CONNECTED 0x2 + #define REDIS_ERROR -1 #define REDIS_REPLY_ERROR 0 #define REDIS_REPLY_STRING 1 @@ -94,6 +98,8 @@ typedef struct redisContext { void *reader; /* Non-reply callbacks */ + redisContextCallback *cbDisconnect; + void *privdataDisconnect; redisContextCallback *cbCommand; void *privdataCommand; redisContextCallback *cbFree; @@ -115,8 +121,10 @@ int redisReplyReaderGetReply(void *reader, void **reply); redisContext *redisConnect(const char *ip, int port, redisReplyFunctions *fn); redisContext *redisConnectNonBlock(const char *ip, int port, redisReplyFunctions *fn); +void redisSetDisconnectCallback(redisContext *c, redisContextCallback *fn, void *privdata); void redisSetCommandCallback(redisContext *c, redisContextCallback *fn, void *privdata); void redisSetFreeCallback(redisContext *c, redisContextCallback *fn, void *privdata); +void redisDisconnect(redisContext *c); void redisFree(redisContext *c); int redisBufferRead(redisContext *c); int redisBufferWrite(redisContext *c, int *done);