Commit 68d71d83 authored by zhaozhao.zz's avatar zhaozhao.zz Committed by antirez
Browse files

expires: refactoring judgment about whether a key is expired

Calling lookupKey*() many times to search a key in one command
may get different result.

That's because lookupKey*() calls expireIfNeeded(), and delete
the key when reach the expire time. So we can get an robj before
the expire time, but a NULL after the expire time.

The worst is that may lead to Redis crash, for example
`RPOPLPUSH foo foo` the first time we get a list form `foo` and
hold the pointer, but when we get `foo` again it's expired and
deleted. Now we hold a freed memory, when execute rpoplpushHandlePush()
redis crash.

To fix it, we can refactor the judgment about whether a key is expired,
using the same basetime `server.cmd_start_mstime` instead of calling
mstime() everytime.
parent 62588dbf
...@@ -1140,7 +1140,7 @@ int keyIsExpired(redisDb *db, robj *key) { ...@@ -1140,7 +1140,7 @@ int keyIsExpired(redisDb *db, robj *key) {
* only the first time it is accessed and not in the middle of the * only the first time it is accessed and not in the middle of the
* script execution, making propagation to slaves / AOF consistent. * script execution, making propagation to slaves / AOF consistent.
* See issue #1525 on Github for more information. */ * See issue #1525 on Github for more information. */
mstime_t now = server.lua_caller ? server.lua_time_start : mstime(); mstime_t now = server.lua_caller ? server.lua_time_start : server.cmd_start_mstime;
return now > when; return now > when;
} }
......
...@@ -2730,6 +2730,7 @@ int processCommand(client *c) { ...@@ -2730,6 +2730,7 @@ int processCommand(client *c) {
queueMultiCommand(c); queueMultiCommand(c);
addReply(c,shared.queued); addReply(c,shared.queued);
} else { } else {
server.cmd_start_mstime = mstime();
call(c,CMD_CALL_FULL); call(c,CMD_CALL_FULL);
c->woff = server.master_repl_offset; c->woff = server.master_repl_offset;
if (listLength(server.ready_keys)) if (listLength(server.ready_keys))
......
...@@ -1232,6 +1232,7 @@ struct redisServer { ...@@ -1232,6 +1232,7 @@ struct redisServer {
time_t timezone; /* Cached timezone. As set by tzset(). */ time_t timezone; /* Cached timezone. As set by tzset(). */
int daylight_active; /* Currently in daylight saving time. */ int daylight_active; /* Currently in daylight saving time. */
long long mstime; /* Like 'unixtime' but with milliseconds resolution. */ long long mstime; /* Like 'unixtime' but with milliseconds resolution. */
mstime_t cmd_start_mstime;
/* Pubsub */ /* Pubsub */
dict *pubsub_channels; /* Map channels to list of subscribed clients */ dict *pubsub_channels; /* Map channels to list of subscribed clients */
list *pubsub_patterns; /* A list of pubsub_patterns */ list *pubsub_patterns; /* A list of pubsub_patterns */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment