From: Richard Kettlewell Date: Wed, 25 Nov 2009 11:35:43 +0000 (+0000) Subject: More memory hygeine. X-Git-Tag: branchpoint-5.1~70^2~2 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/commitdiff_plain/b251ac34ba798319d91f362dc738d616bcc516fc More memory hygeine. --- diff --git a/clients/disorder.c b/clients/disorder.c index dac6c25..c622372 100644 --- a/clients/disorder.c +++ b/clients/disorder.c @@ -175,13 +175,12 @@ static void cf_rescan(char attribute((unused)) **argv) { static void cf_somequeue(int (*fn)(disorder_client *c, struct queue_entry **qp)) { - struct queue_entry *q; + struct queue_entry *q, *qbase; - if(fn(getclient(), &q)) exit(EXIT_FAILURE); - while(q) { + if(fn(getclient(), &qbase)) exit(EXIT_FAILURE); + for(q = qbase; q; q = q->next) print_queue_entry(q); - q = q->next; - } + queue_free(qbase, 1); } static void cf_recent(char attribute((unused)) **argv) { diff --git a/lib/client.c b/lib/client.c index c621ead..d7a3564 100644 --- a/lib/client.c +++ b/lib/client.c @@ -653,6 +653,7 @@ static int disorder_somequeue(disorder_client *c, if(!strcmp(l, ".")) { *qt = 0; *qp = qh; + xfree(l); return 0; } q = xmalloc(sizeof *q); @@ -660,6 +661,7 @@ static int disorder_somequeue(disorder_client *c, *qt = q; qt = &q->next; } + xfree(l); } if(ferror(c->fpin)) { byte_xasprintf((char **)&c->last, "input error: %s", strerror(errno)); diff --git a/lib/queue.c b/lib/queue.c index 69a7986..0f39b23 100644 --- a/lib/queue.c +++ b/lib/queue.c @@ -30,6 +30,7 @@ #include "syscalls.h" #include "table.h" #include "printf.h" +#include "vector.h" const char *const playing_states[] = { "failed", @@ -95,11 +96,17 @@ static const char *marshall_long(const struct queue_entry *q, size_t offset) { return xstrdup(buffer); } +static void free_none(struct queue_entry attribute((unused)) *q, + size_t attribute((unused)) offset) { +} + +#define free_long free_none + static int unmarshall_string(char *data, struct queue_entry *q, size_t offset, void attribute((unused)) (*error_handler)(const char *, void *), void attribute((unused)) *u) { - VALUE(q, offset, char *) = data; + VALUE(q, offset, char *) = xstrdup(data); return 0; } @@ -107,6 +114,10 @@ static const char *marshall_string(const struct queue_entry *q, size_t offset) { return VALUE(q, offset, char *); } +static void free_string(struct queue_entry *q, size_t offset) { + xfree(VALUE(q, offset, char *)); +} + static int unmarshall_time_t(char *data, struct queue_entry *q, size_t offset, void (*error_handler)(const char *, void *), @@ -134,6 +145,8 @@ static const char *marshall_time_t(const struct queue_entry *q, size_t offset) { return xstrdup(buffer); } +#define free_time_t free_none + static int unmarshall_state(char *data, struct queue_entry *q, size_t offset, void (*error_handler)(const char *, void *), @@ -176,7 +189,10 @@ static const char *marshall_origin(const struct queue_entry *q, size_t offset) { return track_origins[VALUE(q, offset, enum track_origin)]; } -#define F(n, h) { #n, offsetof(struct queue_entry, n), marshall_##h, unmarshall_##h } +#define free_state free_none +#define free_origin free_none + +#define F(n, h) { #n, offsetof(struct queue_entry, n), marshall_##h, unmarshall_##h, free_##h } static const struct field { const char *name; @@ -185,6 +201,7 @@ static const struct field { int (*unmarshall)(char *data, struct queue_entry *q, size_t offset, void (*error_handler)(const char *, void *), void *u); + void (*free)(struct queue_entry *q, size_t offset); } fields[] = { /* Keep this table sorted. */ F(expected, time_t), @@ -199,6 +216,7 @@ static const struct field { F(when, time_t), F(wstat, long) }; +#define NFIELDS (sizeof fields / sizeof *fields) int queue_unmarshall(struct queue_entry *q, const char *s, void (*error_handler)(const char *, void *), @@ -209,7 +227,9 @@ int queue_unmarshall(struct queue_entry *q, const char *s, q->pid = -1; /* =none */ if(!(vec = split(s, &nvec, SPLIT_QUOTES, error_handler, u))) return -1; - return queue_unmarshall_vec(q, nvec, vec, error_handler, u); + int rc = queue_unmarshall_vec(q, nvec, vec, error_handler, u); + free_strings(nvec, vec); + return rc; } int queue_unmarshall_vec(struct queue_entry *q, int nvec, char **vec, @@ -258,6 +278,16 @@ char *queue_marshall(const struct queue_entry *q) { return r; } +void queue_free(struct queue_entry *q, int rest) { + if(!q) + return; + if(rest) + queue_free(q->next, rest); + for(unsigned n = 0; n < NFIELDS; ++n) + fields[n].free(q, fields[n].offset); + xfree(q); +} + /* Local Variables: c-basic-offset:2 diff --git a/lib/queue.h b/lib/queue.h index 72e3876..c7dbfd2 100644 --- a/lib/queue.h +++ b/lib/queue.h @@ -1,6 +1,6 @@ /* * This file is part of DisOrder. - * Copyright (C) 2004-2008 Richard Kettlewell + * Copyright (C) 2004-2009 Richard Kettlewell * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -231,6 +231,8 @@ int queue_unmarshall_vec(struct queue_entry *q, int nvec, char **vec, char *queue_marshall(const struct queue_entry *q); /* marshall @q@ into a UTF-8 string */ +void queue_free(struct queue_entry *q, int rest); + #endif /* QUEUE_H */ /*