diff --git a/src/redis.c b/src/redis.c index 277d2e4b..8bfcfdaa 100644 --- a/src/redis.c +++ b/src/redis.c @@ -2016,11 +2016,28 @@ void propagate(struct redisCommand *cmd, int dbid, robj **argv, int argc, } /* Used inside commands to schedule the propagation of additional commands - * after the current command is propagated to AOF / Replication. */ + * after the current command is propagated to AOF / Replication. + * + * 'cmd' must be a pointer to the Redis command to replicate, dbid is the + * database ID the command should be propagated into. + * Arguments of the command to propagte are passed as an array of redis + * objects pointers of len 'argc', using the 'argv' vector. + * + * The function does not take a reference to the passed 'argv' vector, + * so it is up to the caller to release the passed argv (but it is usually + * stack allocated). The function autoamtically increments ref count of + * passed objects, so the caller does not need to. */ void alsoPropagate(struct redisCommand *cmd, int dbid, robj **argv, int argc, int target) { - redisOpArrayAppend(&server.also_propagate,cmd,dbid,argv,argc,target); + robj **argvcopy = zmalloc(sizeof(robj*)*argc); + int j; + + for (j = 0; j < argc; j++) { + argvcopy[j] = argv[j]; + incrRefCount(argv[j]); + } + redisOpArrayAppend(&server.also_propagate,cmd,dbid,argvcopy,argc,target); } /* It is possible to call the function forceCommandPropagation() inside a diff --git a/src/t_set.c b/src/t_set.c index 619b0f8a..47aa173a 100644 --- a/src/t_set.c +++ b/src/t_set.c @@ -556,10 +556,12 @@ void spopWithCountCommand(redisClient *c) { { setTypeIterator *si; - robj *objele, **propargv; + robj *objele, *propargv[3]; int element_encoding; addReplyMultiBulkLen(c, elements_returned); + propargv[0] = createStringObject("SREM",4); + propargv[1] = c->argv[1]; si = setTypeInitIterator(aux_set); while ((element_encoding = setTypeNext(si, &objele, &llele)) != -1) { @@ -574,17 +576,13 @@ void spopWithCountCommand(redisClient *c) { addReplyBulk(c, objele); /* Replicate/AOF this command as an SREM operation */ - propargv = zmalloc(sizeof(robj*)*3); - propargv[0] = createStringObject("SREM",4); - propargv[1] = c->argv[1]; - incrRefCount(c->argv[1]); propargv[2] = objele; - incrRefCount(objele); - alsoPropagate(server.sremCommand,c->db->id,propargv,3,REDIS_PROPAGATE_AOF|REDIS_PROPAGATE_REPL); + decrRefCount(objele); server.dirty++; } + decrRefCount(propargv[0]); setTypeReleaseIterator(si); }