summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Noordhuis <pcnoordhuis@gmail.com>2010-10-19 21:16:57 +0200
committerPieter Noordhuis <pcnoordhuis@gmail.com>2010-10-19 21:26:06 +0200
commit0f745d1ac0acc4fa0614ea441272a6f75ff24f71 (patch)
treea02fd8ff4a73ee67d4d1f9b7592cfdc0e6179856
parentbbe007a75a79cd92654e33f61c1330695fc999ed (diff)
Run pending callbacks with NULL reply on redisDisconnect()
-rw-r--r--hiredis.c15
-rw-r--r--libev-example.c1
-rw-r--r--libevent-example.c1
-rw-r--r--test.c21
4 files changed, 31 insertions, 7 deletions
diff --git a/hiredis.c b/hiredis.c
index fdbbd6d..15bc2a7 100644
--- a/hiredis.c
+++ b/hiredis.c
@@ -587,6 +587,21 @@ static redisContext *redisContextInit(redisReplyFunctions *fn) {
}
void redisDisconnect(redisContext *c) {
+ int i;
+ redisCallback cb;
+
+ /* Non-blocking context: call pending callbacks with the NULL reply */
+ if (!(c->flags & REDIS_BLOCK)) {
+ for (i = 0; i < c->cpos; i++) {
+ cb = c->callbacks[i];
+ if (cb.fn != NULL) {
+ cb.fn(c,NULL,cb.privdata);
+ }
+ }
+ /* Reset callback index */
+ c->cpos = 0;
+ }
+
if (c->cbDisconnect.fn != NULL)
c->cbDisconnect.fn(c,c->cbDisconnect.privdata);
close(c->fd);
diff --git a/libev-example.c b/libev-example.c
index 4cf2c0e..49945bf 100644
--- a/libev-example.c
+++ b/libev-example.c
@@ -5,6 +5,7 @@
#include <signal.h>
void getCallback(redisContext *c, redisReply *reply, void *privdata) {
+ if (reply == NULL) return; /* Error */
printf("argv[%s]: %s\n", (char*)privdata, reply->reply);
/* Disconnect after receiving the reply to GET */
diff --git a/libevent-example.c b/libevent-example.c
index ef68674..9c82850 100644
--- a/libevent-example.c
+++ b/libevent-example.c
@@ -5,6 +5,7 @@
#include <signal.h>
void getCallback(redisContext *c, redisReply *reply, void *privdata) {
+ if (reply == NULL) return; /* Error */
printf("argv[%s]: %s\n", (const char*)privdata, reply->reply);
/* Disconnect after receiving the reply to GET */
diff --git a/test.c b/test.c
index aa0f5a0..c91f9d8 100644
--- a/test.c
+++ b/test.c
@@ -202,18 +202,17 @@ static void __test_callback(redisContext *c, void *privdata) {
__test_callback_flags |= (long)privdata;
}
-static long __test_reply_callback_flags = 0;
static void __test_reply_callback(redisContext *c, redisReply *reply, void *privdata) {
((void)c);
/* Shift to detect execution order */
- __test_reply_callback_flags <<= 8;
- __test_reply_callback_flags |= (long)privdata;
- freeReplyObject(reply);
+ __test_callback_flags <<= 8;
+ __test_callback_flags |= (long)privdata;
+ if (reply) freeReplyObject(reply);
}
static redisContext *__connect_nonblock() {
/* Reset callback flags */
- __test_callback_flags = __test_reply_callback_flags = 0;
+ __test_callback_flags = 0;
return redisConnectNonBlock("127.0.0.1", 6379, NULL);
}
@@ -278,11 +277,19 @@ static void test_nonblocking_connection() {
/* Read until at least one callback is executed (the 3 replies will
* arrive in a single packet, causing all callbacks to be executed in
* a single pass). */
- while(__test_reply_callback_flags == 0) {
+ while(__test_callback_flags == 0) {
assert(redisBufferRead(c) == REDIS_OK);
redisProcessCallbacks(c);
}
- test_cond(__test_reply_callback_flags == 0x010203);
+ test_cond(__test_callback_flags == 0x010203);
+ redisFree(c);
+
+ test("redisDisconnect executes pending callbacks with NULL reply: ");
+ c = __connect_nonblock();
+ redisSetDisconnectCallback(c,__test_callback,(void*)1);
+ redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING");
+ redisDisconnect(c);
+ test_cond(__test_callback_flags == 0x0201);
redisFree(c);
}