From 32a078f2f75bcd26cccd17418c901c3b2c85b1cc Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sun, 7 Jul 2013 14:02:40 +0200 Subject: [PATCH] audiod: Fix memory leak on exit: stat client. Currently we don't close stat clients on exit which results in (benign) memory leaks. Introduce the new public close_stat_clients() and call it from clean_exit() to avoid the leak. This patch also removes the pointles local variable "fd". --- audiod.c | 1 + audiod.h | 1 + audiod_command.c | 35 ++++++++++++++++++++++++++++------- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/audiod.c b/audiod.c index 2367d9cb..6afb15ef 100644 --- a/audiod.c +++ b/audiod.c @@ -1143,6 +1143,7 @@ void __noreturn clean_exit(int status, const char *msg) FOR_EACH_SLOT(i) close_slot(i); audiod_cmdline_parser_free(&conf); + close_stat_clients(); exit(status); } diff --git a/audiod.h b/audiod.h index e54a8576..6a1e8f6d 100644 --- a/audiod.h +++ b/audiod.h @@ -74,6 +74,7 @@ struct btr_node *audiod_get_btr_root(void); void stat_client_write_item(int item_num); void clear_and_dump_items(void); +void close_stat_clients(void); /** iterate over all slots */ #define FOR_EACH_SLOT(_slot) for (_slot = 0; _slot < MAX_STREAM_SLOTS; _slot++) diff --git a/audiod_command.c b/audiod_command.c index 332ce85b..118c22a0 100644 --- a/audiod_command.c +++ b/audiod_command.c @@ -109,6 +109,31 @@ static int stat_client_add(int fd, uint64_t mask, int parser_friendly) num_clients++; return 1; } + +static void close_stat_client(struct stat_client *sc) +{ + PARA_INFO_LOG("closing client fd %d\n", sc->fd); + close(sc->fd); + list_del(&sc->node); + free(sc); + num_clients--; +} + +/** + * Empty the status clients list. + * + * This iterates over the list of connected status clients, closes each client + * file descriptor and frees the resources. + */ +void close_stat_clients(void) +{ + struct stat_client *sc, *tmp; + + list_for_each_entry_safe(sc, tmp, &client_list, node) + close_stat_client(sc); + assert(num_clients == 0); +} + /** * Write a message to all connected status clients. * @@ -127,7 +152,7 @@ void stat_client_write_item(int item_num) struct para_buffer *b; list_for_each_entry_safe(sc, tmp, &client_list, node) { - int fd = sc->fd, ret; + int ret; if (!((one << item_num) & sc->item_mask)) continue; @@ -135,15 +160,11 @@ void stat_client_write_item(int item_num) if (!b->buf) (void)WRITE_STATUS_ITEM(b, item_num, "%s\n", msg? msg : ""); - ret = write(fd, b->buf, b->offset); + ret = write(sc->fd, b->buf, b->offset); if (ret == b->offset) continue; /* write error or short write */ - close(fd); - num_clients--; - PARA_INFO_LOG("deleting client on fd %d\n", fd); - list_del(&sc->node); - free(sc); + close_stat_client(sc); dump_stat_client_list(); } free(pb.buf); -- 2.39.5