Compare commits

..
13 changed files with 12 additions and 91 deletions
-7
View File
@@ -12,13 +12,6 @@ for 2.0.
CHANGELOG
---------
What's new in Redis 2.2.7
=========================
* Fixed bug #543-2 (the issue was reopened with a completely different report)
that caused Redis to randomly crash on list push performed against lists
with other clients blocked with BLPOP (or variants).
What's new in Redis 2.2.6
=========================
-7
View File
@@ -364,13 +364,6 @@ vm-pages 134217728
# Virtual Memory implementation.
vm-max-threads 4
################################ LUA SCRIPTING ###############################
# Max execution time of a Lua script in milliseconds.
# This prevents that a programming error generating an infinite loop will block
# your server forever. Set it to 0 or a negative value for unlimited execution.
lua-time-limit 60000
############################### ADVANCED CONFIG ###############################
# Hashes are encoded in a special way (much more memory efficient) when they
-10
View File
@@ -288,8 +288,6 @@ void loadServerConfig(char *filename) {
err = "Target command name already exists"; goto loaderr;
}
}
} else if (!strcasecmp(argv[0],"lua-time-limit") && argc == 2) {
server.lua_time_limit = strtoll(argv[1],NULL,10);
} else {
err = "Bad directive or wrong number of arguments"; goto loaderr;
}
@@ -448,9 +446,6 @@ void configSetCommand(redisClient *c) {
} else if (!strcasecmp(c->argv[2]->ptr,"set-max-intset-entries")) {
if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
server.set_max_intset_entries = ll;
} else if (!strcasecmp(c->argv[2]->ptr,"lua-time-limit")) {
if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
server.lua_time_limit = ll;
} else {
addReplyErrorFormat(c,"Unsupported CONFIG parameter: %s",
(char*)c->argv[2]->ptr);
@@ -602,11 +597,6 @@ void configGetCommand(redisClient *c) {
addReplyBulkLongLong(c,server.set_max_intset_entries);
matches++;
}
if (stringmatch(pattern,"lua-time-limit",0)) {
addReplyBulkCString(c,"lua-time-limit");
addReplyBulkLongLong(c,server.lua_time_limit);
matches++;
}
setDeferredMultiBulkLength(c,replylen,matches*2);
}
+1 -1
View File
@@ -80,7 +80,7 @@ void computeDatasetDigest(unsigned char *final) {
redisDb *db = server.db+j;
if (dictSize(db->dict) == 0) continue;
di = dictGetSafeIterator(db->dict);
di = dictGetIterator(db->dict);
/* hash the DB id, so the same dataset moved in a different
* DB will lead to a different digest */
+5 -15
View File
@@ -244,9 +244,9 @@ int dictRehashMilliseconds(dict *d, int ms) {
}
/* This function performs just a step of rehashing, and only if there are
* no safe iterators bound to our hash table. When we have iterators in the
* middle of a rehashing we can't mess with the two hash tables otherwise
* some element can be missed or duplicated.
* not iterators bound to our hash table. When we have iterators in the middle
* of a rehashing we can't mess with the two hash tables otherwise some element
* can be missed or duplicated.
*
* This function is called by common lookup or update operations in the
* dictionary so that the hash table automatically migrates from H1 to H2
@@ -423,26 +423,17 @@ dictIterator *dictGetIterator(dict *d)
iter->d = d;
iter->table = 0;
iter->index = -1;
iter->safe = 0;
iter->entry = NULL;
iter->nextEntry = NULL;
return iter;
}
dictIterator *dictGetSafeIterator(dict *d) {
dictIterator *i = dictGetIterator(d);
i->safe = 1;
return i;
}
dictEntry *dictNext(dictIterator *iter)
{
while (1) {
if (iter->entry == NULL) {
dictht *ht = &iter->d->ht[iter->table];
if (iter->safe && iter->index == -1 && iter->table == 0)
iter->d->iterators++;
if (iter->index == -1 && iter->table == 0) iter->d->iterators++;
iter->index++;
if (iter->index >= (signed) ht->size) {
if (dictIsRehashing(iter->d) && iter->table == 0) {
@@ -469,8 +460,7 @@ dictEntry *dictNext(dictIterator *iter)
void dictReleaseIterator(dictIterator *iter)
{
if (iter->safe && !(iter->index == -1 && iter->table == 0))
iter->d->iterators--;
if (!(iter->index == -1 && iter->table == 0)) iter->d->iterators--;
zfree(iter);
}
+2 -6
View File
@@ -74,13 +74,10 @@ typedef struct dict {
int iterators; /* number of iterators currently running */
} dict;
/* If safe is set to 1 this is a safe iteartor, that means, you can call
* dictAdd, dictFind, and other functions against the dictionary even while
* iterating. Otherwise it is a non safe iterator, and only dictNext()
* should be called while iterating. */
typedef struct dictIterator {
dict *d;
int table, index, safe;
int table;
int index;
dictEntry *entry, *nextEntry;
} dictIterator;
@@ -135,7 +132,6 @@ dictEntry * dictFind(dict *d, const void *key);
void *dictFetchValue(dict *d, const void *key);
int dictResize(dict *d);
dictIterator *dictGetIterator(dict *d);
dictIterator *dictGetSafeIterator(dict *d);
dictEntry *dictNext(dictIterator *iter);
void dictReleaseIterator(dictIterator *iter);
dictEntry *dictGetRandomKey(dict *d);
+2 -2
View File
@@ -423,7 +423,7 @@ void acceptTcpHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
cfd = anetTcpAccept(server.neterr, fd, cip, &cport);
if (cfd == AE_ERR) {
redisLog(REDIS_WARNING,"Accepting client connection: %s", server.neterr);
redisLog(REDIS_VERBOSE,"Accepting client connection: %s", server.neterr);
return;
}
redisLog(REDIS_VERBOSE,"Accepted %s:%d", cip, cport);
@@ -438,7 +438,7 @@ void acceptUnixHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
cfd = anetUnixAccept(server.neterr, fd);
if (cfd == AE_ERR) {
redisLog(REDIS_WARNING,"Accepting client connection: %s", server.neterr);
redisLog(REDIS_VERBOSE,"Accepting client connection: %s", server.neterr);
return;
}
redisLog(REDIS_VERBOSE,"Accepted connection to %s", server.unixsocket);
-1
View File
@@ -803,7 +803,6 @@ void initServerConfig() {
server.list_max_ziplist_value = REDIS_LIST_MAX_ZIPLIST_VALUE;
server.set_max_intset_entries = REDIS_SET_MAX_INTSET_ENTRIES;
server.shutdown_asap = 0;
server.lua_time_limit = REDIS_LUA_TIME_LIMIT;
updateLRUClock();
resetServerSaveParams();
-6
View File
@@ -213,9 +213,6 @@
#define REDIS_MAXMEMORY_ALLKEYS_RANDOM 4
#define REDIS_MAXMEMORY_NO_EVICTION 5
/* Scripting */
#define REDIS_LUA_TIME_LIMIT 60000 /* milliseconds */
/* We can print the stacktrace, so our assert is defined this way: */
#define redisAssert(_e) ((_e)?(void)0 : (_redisAssert(#_e,__FILE__,__LINE__),_exit(1)))
#define redisPanic(_e) _redisPanic(#_e,__FILE__,__LINE__),_exit(1)
@@ -501,8 +498,6 @@ struct redisServer {
/* Scripting */
lua_State *lua;
redisClient *lua_client;
long long lua_time_limit;
long long lua_time_start;
};
typedef struct pubsubPattern {
@@ -873,7 +868,6 @@ int isStringRepresentableAsLong(sds s, long *longval);
int isStringRepresentableAsLongLong(sds s, long long *longval);
int isObjectRepresentableAsLongLong(robj *o, long long *llongval);
int string2ll(char *s, size_t slen, long long *value);
long long ustime(void);
/* Configuration */
void loadServerConfig(char *filename);
-23
View File
@@ -199,18 +199,6 @@ int luaRedisCommand(lua_State *lua) {
return 1;
}
void luaMaskCountHook(lua_State *lua, lua_Debug *ar) {
long long elapsed;
REDIS_NOTUSED(ar);
elapsed = (ustime()/1000) - server.lua_time_start;
if (elapsed >= server.lua_time_limit) {
redisLog(REDIS_NOTICE,"Lua script aborted for max execution time after %lld milliseconds of running time.",elapsed);
lua_pushstring(lua,"Script aborted for max execution time.");
lua_error(lua);
}
}
void scriptingInit(void) {
lua_State *lua = lua_open();
luaL_openlibs(lua);
@@ -384,17 +372,6 @@ void evalCommand(redisClient *c) {
/* Select the right DB in the context of the Lua client */
selectDb(server.lua_client,c->db->id);
/* Set an hook in order to be able to stop the script execution if it
* is running for too much time.
* We set the hook only if the time limit is enabled as the hook will
* make the Lua script execution slower. */
if (server.lua_time_limit > 0) {
lua_sethook(lua,luaMaskCountHook,LUA_MASKCOUNT,100000);
server.lua_time_start = ustime()/1000;
} else {
lua_sethook(lua,luaMaskCountHook,0,0);
}
/* At this point whatever this script was never seen before or if it was
* already defined, we can call it. We have zero arguments and expect
* a single return value. */
+1
View File
@@ -817,6 +817,7 @@ int handleClientsWaitingListPush(redisClient *c, robj *key, robj *ele) {
/* This should remove the first element of the "clients" list. */
unblockClientWaitingData(receiver);
redisAssert(ln != listFirst(clients));
if (dstkey == NULL) {
/* BRPOP/BLPOP */
-12
View File
@@ -1,7 +1,6 @@
#include "redis.h"
#include <ctype.h>
#include <limits.h>
#include <sys/time.h>
/* Glob-style pattern matching. */
int stringmatchlen(const char *pattern, int patternLen,
@@ -302,14 +301,3 @@ int string2ll(char *s, size_t slen, long long *value) {
}
return 1;
}
/* Return the UNIX time in microseconds */
long long ustime(void) {
struct timeval tv;
long long ust;
gettimeofday(&tv, NULL);
ust = ((long long)tv.tv_sec)*1000000;
ust += tv.tv_usec;
return ust;
}
+1 -1
View File
@@ -1 +1 @@
#define REDIS_VERSION "2.2.107"
#define REDIS_VERSION "2.2.106"