From: Joseph Jang Date: Thu, 29 Mar 2012 17:06:53 +0000 (+0900) Subject: Fixed a memory leak with replication X-Git-Url: https://git.saurik.com/redis.git/commitdiff_plain/f892797e1b459ad568df32d891b368302c40b3c9 Fixed a memory leak with replication occurs when two or more dbs are replicated and at least one of them is >db10 --- diff --git a/src/redis.c b/src/redis.c index 7ddeb886..866076b1 100644 --- a/src/redis.c +++ b/src/redis.c @@ -977,16 +977,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 5a3d1a9c..bdb033a8 100644 --- a/src/redis.h +++ b/src/redis.h @@ -44,6 +44,7 @@ #define REDIS_CONFIGLINE_MAX 1024 #define REDIS_EXPIRELOOKUPS_PER_CRON 10 /* lookup 10 expires per loop */ #define REDIS_MAX_WRITE_PER_EVENT (1024*64) +#define REDIS_SHARED_SELECT_CMDS 10 #define REDIS_SHARED_INTEGERS 10000 #define REDIS_SHARED_BULKHDR_LEN 32 #define REDIS_MAX_LOGMSG_LEN 1024 /* Default maximum length of syslog messages */ @@ -366,10 +367,9 @@ struct sharedObjectsStruct { *colon, *nullbulk, *nullmultibulk, *queued, *emptymultibulk, *wrongtypeerr, *nokeyerr, *syntaxerr, *sameobjecterr, *outofrangeerr, *noscripterr, *loadingerr, *slowscripterr, *bgsaveerr, - *roslaveerr, *oomerr, *plus, *select0, *select1, *select2, *select3, - *select4, *select5, *select6, *select7, *select8, *select9, - *messagebulk, *pmessagebulk, *subscribebulk, *unsubscribebulk, - *psubscribebulk, *punsubscribebulk, *del, *rpop, *lpop, + *roslaveerr, *oomerr, *plus, *messagebulk, *pmessagebulk, *subscribebulk, + *unsubscribebulk, *psubscribebulk, *punsubscribebulk, *del, *rpop, *lpop, + *select[REDIS_SHARED_SELECT_CMDS], *integers[REDIS_SHARED_INTEGERS], *mbulkhdr[REDIS_SHARED_BULKHDR_LEN], /* "*\r\n" */ *bulkhdr[REDIS_SHARED_BULKHDR_LEN]; /* "$\r\n" */ diff --git a/src/replication.c b/src/replication.c index c99be32a..f474d982 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);