chiark / gitweb /
More memory hygeine.
authorRichard Kettlewell <rjk@greenend.org.uk>
Wed, 25 Nov 2009 11:35:43 +0000 (11:35 +0000)
committerRichard Kettlewell <rjk@greenend.org.uk>
Wed, 25 Nov 2009 11:35:43 +0000 (11:35 +0000)
clients/disorder.c
lib/client.c
lib/queue.c
lib/queue.h

index dac6c25..c622372 100644 (file)
@@ -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) {
index c621ead..d7a3564 100644 (file)
@@ -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));
index 69a7986..0f39b23 100644 (file)
@@ -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
index 72e3876..c7dbfd2 100644 (file)
@@ -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 */
 
 /*