summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2015-05-14 13:39:26 +0200
committerantirez <antirez@gmail.com>2015-05-14 13:39:26 +0200
commit5a0516b5b96b7bbd16c1942b281c798f3db03630 (patch)
treee7173a35dc8db23064dff4cc06c0edeba4056e01
parent05dbc820051daab748761ec67c9c1bba37f2717e (diff)
downloadredis-5a0516b5b96b7bbd16c1942b281c798f3db03630.tar.gz
Sentinel: rewrite callback chain removing instances with shared links
Otherwise pending commands callbacks will fire with a reference that no longer exists.
-rw-r--r--src/sentinel.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/sentinel.c b/src/sentinel.c
index 57d5fd27d..0d33d8219 100644
--- a/src/sentinel.c
+++ b/src/sentinel.c
@@ -969,7 +969,23 @@ instanceLink *releaseInstanceLink(instanceLink *link, sentinelRedisInstance *ri)
link->refcount--;
if (link->refcount != 0) {
if (ri) {
- /* TODO: run the callbacks list and rebind. */
+ /* This instance may have pending callbacks in the hiredis async
+ * context, having as 'privdata' the instance that we are going to
+ * free. Let's rewrite the callback list, directly exploiting
+ * hiredis internal data structures, in order to bind them with
+ * a callback that will ignore the reply at all. */
+ redisCallback *cb;
+ redisCallbackList *callbacks = &link->cc->replies;
+
+ cb = callbacks->head;
+ while(cb) {
+ if (cb->privdata == ri) {
+ printf("HERE\n");
+ cb->fn = sentinelDiscardReplyCallback;
+ cb->privdata = NULL; /* Not strictly needed. */
+ }
+ cb = cb->next;
+ }
}
return link; /* Other active users. */
}