audiod: Fix memory leak on exit: close slots.
authorAndre Noll <maan@systemlinux.org>
Sat, 6 Jul 2013 20:26:03 +0000 (22:26 +0200)
committerAndre Noll <maan@systemlinux.org>
Sun, 22 Sep 2013 00:29:18 +0000 (02:29 +0200)
Currently we don't bother to close slots on exit. This is no problem
but it causes valgrind to report a bunch of memory leaks. This patch
makes it close all writers, filters and receivers on exit.

To this aim, the cleanup part of close_unused_slots() is abstracted out
into the new close_slot(), which is now also called from clean_exit()
for each slot, just before para_audiod exits. In order to avoid
forward declarations, clean_exit() had to be moved below the two
other functions.

audiod.c

index 687fc5c..d2a58bb 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -1069,27 +1069,6 @@ static void close_stat_pipe(void)
        audiod_status_dump();
 }
 
-/**
- * close the connection to para_server and exit
- *
- * \param status the exit status which is passed to exit(3)
- * \param msg the log message
- *
- * Log \a msg with loglevel \p EMERG, close the connection to para_server if
- * open, and call \p exit(status). \a status should be either EXIT_SUCCESS or
- * EXIT_FAILURE.
- *
- * \sa exit(3)
- */
-void __noreturn clean_exit(int status, const char *msg)
-{
-       PARA_EMERG_LOG("%s\n", msg);
-       if (socket_name)
-               unlink(socket_name);
-       close_stat_pipe();
-       exit(status);
-}
-
 /* avoid busy loop if server is down */
 static void set_stat_task_restart_barrier(unsigned seconds)
 {
@@ -1121,20 +1100,49 @@ static bool must_close_slot(int slot_num)
        return true;
 }
 
+static void close_slot(int slot_num)
+{
+       struct slot_info *s = slot + slot_num;
+
+       PARA_INFO_LOG("closing slot %d\n", slot_num);
+       close_writers(s);
+       close_filters(s);
+       close_receiver(slot_num);
+       clear_slot(slot_num);
+}
+
 static void close_unused_slots(void)
 {
        int i;
 
-       FOR_EACH_SLOT(i) {
-               struct slot_info *s = slot + i;
-               if (!must_close_slot(i))
-                       continue;
-               PARA_INFO_LOG("closing slot %d\n", i);
-               close_writers(s);
-               close_filters(s);
-               close_receiver(i);
-               clear_slot(i);
-       }
+       FOR_EACH_SLOT(i)
+               if (must_close_slot(i))
+                       close_slot(i);
+}
+
+/**
+ * Close the connection to para_server and exit.
+ *
+ * \param status The exit status which is passed to exit(3).
+ * \param msg The log message
+ *
+ * Log \a msg with loglevel \p EMERG, close the connection to para_server and
+ * all slots, and call \p exit(status). \a status should be either EXIT_SUCCESS
+ * or EXIT_FAILURE.
+ *
+ * \sa exit(3).
+ */
+void __noreturn clean_exit(int status, const char *msg)
+{
+       int i;
+
+       PARA_EMERG_LOG("%s\n", msg);
+       if (socket_name)
+               unlink(socket_name);
+       close_stat_pipe();
+       FOR_EACH_SLOT(i)
+               close_slot(i);
+       exit(status);
 }
 
 /*