mirror of
https://github.com/fluencelabs/redis
synced 2025-03-30 22:31:03 +00:00
Correct cleanup when aborting AOF loading.
Because of the new ability to start with a truncated AOF, we need to correctly release all the memory on EOF error. Otherwise there is a small leak, that is not really a problem, but causes a false positive in the tests that detect memory leaks.
This commit is contained in:
parent
132550efc3
commit
de663966c6
37
src/aof.c
37
src/aof.c
@ -577,6 +577,14 @@ struct redisClient *createFakeClient(void) {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void freeFakeClientArgv(struct redisClient *c) {
|
||||||
|
int j;
|
||||||
|
|
||||||
|
for (j = 0; j < c->argc; j++)
|
||||||
|
decrRefCount(c->argv[j]);
|
||||||
|
zfree(c->argv);
|
||||||
|
}
|
||||||
|
|
||||||
void freeFakeClient(struct redisClient *c) {
|
void freeFakeClient(struct redisClient *c) {
|
||||||
sdsfree(c->querybuf);
|
sdsfree(c->querybuf);
|
||||||
listRelease(c->reply);
|
listRelease(c->reply);
|
||||||
@ -639,14 +647,30 @@ int loadAppendOnlyFile(char *filename) {
|
|||||||
if (argc < 1) goto fmterr;
|
if (argc < 1) goto fmterr;
|
||||||
|
|
||||||
argv = zmalloc(sizeof(robj*)*argc);
|
argv = zmalloc(sizeof(robj*)*argc);
|
||||||
|
fakeClient->argc = argc;
|
||||||
|
fakeClient->argv = argv;
|
||||||
|
|
||||||
for (j = 0; j < argc; j++) {
|
for (j = 0; j < argc; j++) {
|
||||||
if (fgets(buf,sizeof(buf),fp) == NULL) goto readerr;
|
if (fgets(buf,sizeof(buf),fp) == NULL) {
|
||||||
|
fakeClient->argc = j; /* Free up to j-1. */
|
||||||
|
freeFakeClientArgv(fakeClient);
|
||||||
|
goto readerr;
|
||||||
|
}
|
||||||
if (buf[0] != '$') goto fmterr;
|
if (buf[0] != '$') goto fmterr;
|
||||||
len = strtol(buf+1,NULL,10);
|
len = strtol(buf+1,NULL,10);
|
||||||
argsds = sdsnewlen(NULL,len);
|
argsds = sdsnewlen(NULL,len);
|
||||||
if (len && fread(argsds,len,1,fp) == 0) goto readerr;
|
if (len && fread(argsds,len,1,fp) == 0) {
|
||||||
|
sdsfree(argsds);
|
||||||
|
fakeClient->argc = j; /* Free up to j-1. */
|
||||||
|
freeFakeClientArgv(fakeClient);
|
||||||
|
goto readerr;
|
||||||
|
}
|
||||||
argv[j] = createObject(REDIS_STRING,argsds);
|
argv[j] = createObject(REDIS_STRING,argsds);
|
||||||
if (fread(buf,2,1,fp) == 0) goto readerr; /* discard CRLF */
|
if (fread(buf,2,1,fp) == 0) {
|
||||||
|
fakeClient->argc = j+1; /* Free up to j. */
|
||||||
|
freeFakeClientArgv(fakeClient);
|
||||||
|
goto readerr; /* discard CRLF */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Command lookup */
|
/* Command lookup */
|
||||||
@ -655,9 +679,8 @@ int loadAppendOnlyFile(char *filename) {
|
|||||||
redisLog(REDIS_WARNING,"Unknown command '%s' reading the append only file", (char*)argv[0]->ptr);
|
redisLog(REDIS_WARNING,"Unknown command '%s' reading the append only file", (char*)argv[0]->ptr);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run the command in the context of a fake client */
|
/* Run the command in the context of a fake client */
|
||||||
fakeClient->argc = argc;
|
|
||||||
fakeClient->argv = argv;
|
|
||||||
cmd->proc(fakeClient);
|
cmd->proc(fakeClient);
|
||||||
|
|
||||||
/* The fake client should not have a reply */
|
/* The fake client should not have a reply */
|
||||||
@ -667,9 +690,7 @@ int loadAppendOnlyFile(char *filename) {
|
|||||||
|
|
||||||
/* Clean up. Command code may have changed argv/argc so we use the
|
/* Clean up. Command code may have changed argv/argc so we use the
|
||||||
* argv/argc of the client instead of the local variables. */
|
* argv/argc of the client instead of the local variables. */
|
||||||
for (j = 0; j < fakeClient->argc; j++)
|
freeFakeClientArgv(fakeClient);
|
||||||
decrRefCount(fakeClient->argv[j]);
|
|
||||||
zfree(fakeClient->argv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This point can only be reached when EOF is reached without errors.
|
/* This point can only be reached when EOF is reached without errors.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user