From e95ca1db21b2dbe82f39a3f7f6390cb5f58dafae Mon Sep 17 00:00:00 2001 From: Joseph Jang Date: Fri, 30 Mar 2012 02:06:53 +0900 Subject: [PATCH] Fixed a memory leak with replication occurs when two or more dbs are replicated and at least one of them is >db10 --- src/redis.c | 15 +++++---------- src/redis.h | 4 ++-- src/replication.c | 19 +++++-------------- 3 files changed, 12 insertions(+), 26 deletions(-) diff --git a/src/redis.c b/src/redis.c index cc6edd73..53583a0a 100644 --- a/src/redis.c +++ b/src/redis.c @@ -773,16 +773,11 @@ void createSharedObjects(void) { shared.space = createObject(REDIS_STRING,sdsnew(" ")); shared.colon = createObject(REDIS_STRING,sdsnew(":")); shared.plus = createObject(REDIS_STRING,sdsnew("+")); - shared.select0 = createStringObject("select 0\r\n",10); - shared.select1 = createStringObject("select 1\r\n",10); - shared.select2 = createStringObject("select 2\r\n",10); - shared.select3 = createStringObject("select 3\r\n",10); - shared.select4 = createStringObject("select 4\r\n",10); - shared.select5 = createStringObject("select 5\r\n",10); - shared.select6 = createStringObject("select 6\r\n",10); - shared.select7 = createStringObject("select 7\r\n",10); - shared.select8 = createStringObject("select 8\r\n",10); - shared.select9 = createStringObject("select 9\r\n",10); + + for (j = 0; j < REDIS_SHARED_SELECT_CMDS; j++) { + shared.select[j] = createObject(REDIS_STRING, + sdscatprintf(sdsempty(),"select %d\r\n", j)); + } shared.messagebulk = createStringObject("$7\r\nmessage\r\n",13); shared.pmessagebulk = createStringObject("$8\r\npmessage\r\n",14); shared.subscribebulk = createStringObject("$9\r\nsubscribe\r\n",15); diff --git a/src/redis.h b/src/redis.h index e93916c3..f2ca117d 100644 --- a/src/redis.h +++ b/src/redis.h @@ -47,6 +47,7 @@ #define REDIS_EXPIRELOOKUPS_PER_CRON 10 /* lookup 10 expires per loop */ #define REDIS_MAX_WRITE_PER_EVENT (1024*64) #define REDIS_REQUEST_MAX_SIZE (1024*1024*256) /* max bytes in inline command */ +#define REDIS_SHARED_SELECT_CMDS 10 #define REDIS_SHARED_INTEGERS 10000 #define REDIS_REPLY_CHUNK_BYTES (5*1500) /* 5 TCP packets with default MTU */ #define REDIS_INLINE_MAX_SIZE (1024*64) /* Max size of inline reads */ @@ -372,8 +373,7 @@ struct sharedObjectsStruct { *colon, *nullbulk, *nullmultibulk, *queued, *emptymultibulk, *wrongtypeerr, *nokeyerr, *syntaxerr, *sameobjecterr, *outofrangeerr, *loadingerr, *plus, - *select0, *select1, *select2, *select3, *select4, - *select5, *select6, *select7, *select8, *select9, + *select[REDIS_SHARED_SELECT_CMDS], *messagebulk, *pmessagebulk, *subscribebulk, *unsubscribebulk, *mbulk3, *mbulk4, *psubscribebulk, *punsubscribebulk, *integers[REDIS_SHARED_INTEGERS]; diff --git a/src/replication.c b/src/replication.c index 2e441f5b..e0d4aeff 100644 --- a/src/replication.c +++ b/src/replication.c @@ -25,24 +25,15 @@ void replicationFeedSlaves(list *slaves, int dictid, robj **argv, int argc) { if (slave->slaveseldb != dictid) { robj *selectcmd; - switch(dictid) { - case 0: selectcmd = shared.select0; break; - case 1: selectcmd = shared.select1; break; - case 2: selectcmd = shared.select2; break; - case 3: selectcmd = shared.select3; break; - case 4: selectcmd = shared.select4; break; - case 5: selectcmd = shared.select5; break; - case 6: selectcmd = shared.select6; break; - case 7: selectcmd = shared.select7; break; - case 8: selectcmd = shared.select8; break; - case 9: selectcmd = shared.select9; break; - default: + if (dictid >= 0 && dictid < REDIS_SHARED_SELECT_CMDS) { + incrRefCount(shared.select[dictid]); + selectcmd = shared.select[dictid]; + } else { selectcmd = createObject(REDIS_STRING, sdscatprintf(sdsempty(),"select %d\r\n",dictid)); - selectcmd->refcount = 0; - break; } addReply(slave,selectcmd); + decrRefCount(selectcmd); slave->slaveseldb = dictid; } addReplyMultiBulkLen(slave,argc);