From 58713c6b13ebe736ad33ff48fba13a1db5d58e68 Mon Sep 17 00:00:00 2001 From: antirez Date: Thu, 5 Dec 2013 14:55:07 +0100 Subject: [PATCH] Fix clients timeout handling. During the refactoring of blocking operations, commit 82b672f6335ac2db32a724ba5dc10398c949a4a8, a bug was introduced where a milliseconds time is compared to a seconds time, so all the clients always appear to timeout if timeout is set to non-zero value. Thanks to Jonathan Leibiusky for finding the bug and helping verifying the cause and fix. --- src/redis.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/redis.c b/src/redis.c index 72c9f661..9c92aaf3 100644 --- a/src/redis.c +++ b/src/redis.c @@ -872,7 +872,7 @@ long long getOperationsPerSecond(void) { /* Check for timeouts. Returns non-zero if the client was terminated */ int clientsCronHandleTimeout(redisClient *c) { - mstime_t now = mstime(); + time_t now = server.unixtime; if (server.maxidletime && !(c->flags & REDIS_SLAVE) && /* no timeout for slaves */ @@ -886,7 +886,12 @@ int clientsCronHandleTimeout(redisClient *c) { freeClient(c); return 1; } else if (c->flags & REDIS_BLOCKED) { - if (c->bpop.timeout != 0 && c->bpop.timeout < now) { + /* Blocked OPS timeout is handled with milliseconds resolution. + * However note that the actual resolution is limited by + * server.hz. */ + mstime_t now_ms = mstime(); + + if (c->bpop.timeout != 0 && c->bpop.timeout < now_ms) { replyToBlockedClientTimedOut(c); unblockClient(c); }