From d8f25ce3ac7538a757ab2a1d17907d98c38c1adb Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Thu, 22 Jul 2010 15:55:41 +0200 Subject: [PATCH] fix rare condition where 'key' would already be destroyed while is was needed later on --- redis.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/redis.c b/redis.c index e5afad4e..c7310a12 100644 --- a/redis.c +++ b/redis.c @@ -9870,6 +9870,11 @@ static int dontWaitForSwappedKey(redisClient *c, robj *key) { listIter li; struct dictEntry *de; + /* The key object might be destroyed when deleted from the c->io_keys + * list (and the "key" argument is physically the same object as the + * object inside the list), so we need to protect it. */ + incrRefCount(key); + /* Remove the key from the list of keys this client is waiting for. */ listRewind(c->io_keys,&li); while ((ln = listNext(&li)) != NULL) { @@ -9878,18 +9883,19 @@ static int dontWaitForSwappedKey(redisClient *c, robj *key) { break; } } - assert(ln != NULL); + redisAssert(ln != NULL); /* Remove the client form the key => waiting clients map. */ de = dictFind(c->db->io_keys,key); - assert(de != NULL); + redisAssert(de != NULL); l = dictGetEntryVal(de); ln = listSearchKey(l,c); - assert(ln != NULL); + redisAssert(ln != NULL); listDelNode(l,ln); if (listLength(l) == 0) dictDelete(c->db->io_keys,key); + decrRefCount(key); return listLength(c->io_keys) == 0; }