summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2010-09-07 13:16:39 +0200
committerantirez <antirez@gmail.com>2010-09-07 13:16:39 +0200
commit521cdafafef93cd277a77100d596b861b773505b (patch)
tree2088ab628517113b82955c97f17e95083f2f8102
parent00a90feb0b3dabfab683875ae7d907f1e39cd80e (diff)
downloadredis-521cdafafef93cd277a77100d596b861b773505b.tar.gz
avoid actively expiring keys in the cron loop if this keys are being swapped or loaded. This avoids a rare race condition
-rw-r--r--redis.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/redis.c b/redis.c
index bdc23af14..308f9e784 100644
--- a/redis.c
+++ b/redis.c
@@ -1515,10 +1515,21 @@ static int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientD
num = REDIS_EXPIRELOOKUPS_PER_CRON;
while (num--) {
dictEntry *de;
+ robj *key;
time_t t;
if ((de = dictGetRandomKey(db->expires)) == NULL) break;
t = (time_t) dictGetEntryVal(de);
+ key = dictGetEntryKey(de);
+ /* Don't expire keys that are in the contest of I/O jobs.
+ * Otherwise decrRefCount will kill the I/O thread and
+ * clients waiting for this keys will wait forever.
+ *
+ * In general this change will not have any impact on the
+ * performance of the expiring algorithm but it's much safer. */
+ if (server.vm_enabled &&
+ (key->storage == REDIS_VM_SWAPPING ||
+ key->storage == REDIS_VM_LOADING)) continue;
if (now > t) {
deleteKey(db,dictGetEntryKey(de));
expired++;