mirror of
https://github.com/fluencelabs/redis
synced 2025-06-19 12:11:21 +00:00
fix rare condition where 'key' would already be destroyed while is was needed later on
This commit is contained in:
12
redis.c
12
redis.c
@ -9870,6 +9870,11 @@ static int dontWaitForSwappedKey(redisClient *c, robj *key) {
|
|||||||
listIter li;
|
listIter li;
|
||||||
struct dictEntry *de;
|
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. */
|
/* Remove the key from the list of keys this client is waiting for. */
|
||||||
listRewind(c->io_keys,&li);
|
listRewind(c->io_keys,&li);
|
||||||
while ((ln = listNext(&li)) != NULL) {
|
while ((ln = listNext(&li)) != NULL) {
|
||||||
@ -9878,18 +9883,19 @@ static int dontWaitForSwappedKey(redisClient *c, robj *key) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(ln != NULL);
|
redisAssert(ln != NULL);
|
||||||
|
|
||||||
/* Remove the client form the key => waiting clients map. */
|
/* Remove the client form the key => waiting clients map. */
|
||||||
de = dictFind(c->db->io_keys,key);
|
de = dictFind(c->db->io_keys,key);
|
||||||
assert(de != NULL);
|
redisAssert(de != NULL);
|
||||||
l = dictGetEntryVal(de);
|
l = dictGetEntryVal(de);
|
||||||
ln = listSearchKey(l,c);
|
ln = listSearchKey(l,c);
|
||||||
assert(ln != NULL);
|
redisAssert(ln != NULL);
|
||||||
listDelNode(l,ln);
|
listDelNode(l,ln);
|
||||||
if (listLength(l) == 0)
|
if (listLength(l) == 0)
|
||||||
dictDelete(c->db->io_keys,key);
|
dictDelete(c->db->io_keys,key);
|
||||||
|
|
||||||
|
decrRefCount(key);
|
||||||
return listLength(c->io_keys) == 0;
|
return listLength(c->io_keys) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user