From d136b3c1b70d7ae687b763c59d1bc03d4ad3dbc2 Mon Sep 17 00:00:00 2001 From: sinanmohd Date: Sun, 16 Jun 2024 13:17:35 +0530 Subject: c: improve memory management --- flake.nix | 1 + include/util.h | 14 ++++++++++++++ src/jobs.c | 14 ++++++-------- src/queue.c | 9 ++++----- src/util.c | 15 +++++++++------ 5 files changed, 34 insertions(+), 19 deletions(-) diff --git a/flake.nix b/flake.nix index 33f3798..a1192f6 100644 --- a/flake.nix +++ b/flake.nix @@ -29,6 +29,7 @@ gdb ccls + valgrind clang-tools # clang-format ]; diff --git a/include/util.h b/include/util.h index c5aa0ab..5279a07 100644 --- a/include/util.h +++ b/include/util.h @@ -5,5 +5,19 @@ #define print_err(fmt, ...) \ fprintf(stderr, "[%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) +#define LIST_FOREACH_FREE(cur, next, head, field, func_free) \ + for ((cur) = ((head)->lh_first); (cur);) { \ + (next) = ((cur)->field.le_next); \ + func_free((cur)); \ + (cur) = (next); \ + } + +#define CIRCLEQ_FOREACH_FREE(cur, next, head, field, func_free) \ + for ((cur) = ((head)->cqh_first); (cur) != (const void *)(head);) { \ + (next) = ((cur)->field.cqe_next); \ + func_free((cur)); \ + (cur) = (next); \ + } + int json_streaming_read(FILE *stream, cJSON **json); int vpopen(FILE **stream, const char *file, char *const argv[]); diff --git a/src/jobs.c b/src/jobs.c index c6141e6..a7c3953 100644 --- a/src/jobs.c +++ b/src/jobs.c @@ -213,8 +213,8 @@ out_free: void job_free(struct job *job) { - struct job *j; - struct output *o; + struct job *job_cur, *job_next; + struct output *op_cur, *op_next; if (job == NULL) return; @@ -222,11 +222,8 @@ void job_free(struct job *job) free(job->name); free(job->drv_path); - LIST_FOREACH (o, &job->outputs, dlist) - output_free(o); - - LIST_FOREACH (j, &job->deps, dlist) - job_free(j); + LIST_FOREACH_FREE(op_cur, op_next, &job->outputs, dlist, output_free); + LIST_FOREACH_FREE(job_cur, job_next, &job->deps, dlist, job_free); free(job); } @@ -257,7 +254,8 @@ int jobs_init(FILE **stream) /* TODO: proproperly handle args */ char *const args[] = { "nix-eval-jobs", - "", + "--flake", + "github:sinanmohd/evanix#packages.x86_64-linux", NULL, }; diff --git a/src/queue.c b/src/queue.c index e1e41ec..191c3f8 100644 --- a/src/queue.c +++ b/src/queue.c @@ -65,16 +65,14 @@ static void queue_push(struct queue *queue, struct job *job) void queue_thread_free(struct queue_thread *queue_thread) { - struct job *job; + struct job *cur, *next; int ret; if (queue_thread == NULL) return; - CIRCLEQ_FOREACH (job, &queue_thread->queue->jobs, clist) { - CIRCLEQ_REMOVE(&queue_thread->queue->jobs, job, clist); - free(job); - } + CIRCLEQ_FOREACH_FREE(cur, next, &queue_thread->queue->jobs, clist, + job_free); ret = sem_destroy(&queue_thread->queue->sem); if (ret < 0) @@ -85,6 +83,7 @@ void queue_thread_free(struct queue_thread *queue_thread) free(queue_thread->queue); fclose(queue_thread->stream); + free(queue_thread); } int queue_thread_new(struct queue_thread **queue_thread, FILE *stream) diff --git a/src/util.c b/src/util.c index 001180e..e84a72a 100644 --- a/src/util.c +++ b/src/util.c @@ -10,28 +10,31 @@ int json_streaming_read(FILE *stream, cJSON **json) { - int ret; size_t n; + int ret; char *line = NULL; ret = getline(&line, &n, stream); if (ret < 0) { if (errno != 0) { print_err("%s", strerror(errno)); - return -errno; + ret = -errno; } + ret = -EOF; - return -EOF; + goto out_free_line; } *json = cJSON_Parse(line); - free(line); if (cJSON_IsInvalid(*json)) { print_err("%s", "Invalid JSON"); - return -EPERM; + ret = -EPERM; + goto out_free_line; } - return 0; +out_free_line: + free(line); + return ret; } int vpopen(FILE **stream, const char *file, char *const argv[]) -- cgit v1.2.3