]> git.alsa-project.org Git - alsa-utils.git/commitdiff
alsactl: use link list to maintain source of events
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sun, 14 Oct 2018 14:36:29 +0000 (23:36 +0900)
committerJaroslav Kysela <perex@perex.cz>
Sun, 14 Oct 2018 14:57:15 +0000 (16:57 +0200)
At present, handlers for control nodes are maintained by one-dimensional
array. This is not necessarily useful to maintain handlers with
associated information.

This commit adds link-list for the maintenance.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
alsactl/monitor.c

index 7050eebf08d107d841e4a531a3b17bf4f31b0363..7a61f9cd515db64cb178fd8776aba0002fb6c56d 100644 (file)
 #include <sys/epoll.h>
 #include <alsa/asoundlib.h>
 
+#include <stddef.h>
+#include "list.h"
+
+struct src_entry {
+       snd_ctl_t *handle;
+       char *name;
+       unsigned int pfd_count;
+       struct list_head list;
+};
+
 #define MAX_CARDS      256
 
 struct snd_card_iterator {
@@ -55,6 +65,59 @@ static const char *snd_card_iterator_next(struct snd_card_iterator *iter)
         return (const char *)iter->name;
 }
 
+static void remove_source_entry(struct src_entry *entry)
+{
+       list_del(&entry->list);
+       free(entry->name);
+       free(entry);
+}
+
+static void clear_source_list(struct list_head *srcs)
+{
+       struct src_entry *entry, *tmp;
+
+       list_for_each_entry_safe(entry, tmp, srcs, list)
+               remove_source_entry(entry);
+}
+
+static int insert_source_entry(struct list_head *srcs, snd_ctl_t *handle,
+                              const char *name)
+{
+       struct src_entry *entry;
+       int count;
+       int err;
+
+       entry = calloc(1, sizeof(*entry));
+       if (!entry)
+               return -ENOMEM;
+       INIT_LIST_HEAD(&entry->list);
+       entry->handle = handle;
+
+       entry->name = strdup(name);
+       if (!entry->name) {
+               err = -ENOMEM;
+               goto error;
+       }
+
+       count = snd_ctl_poll_descriptors_count(handle);
+       if (count < 0) {
+               err = count;
+               goto error;
+       }
+       if (count == 0) {
+               err = -ENXIO;
+               goto error;
+       }
+       entry->pfd_count = count;
+
+       list_add_tail(&entry->list, srcs);
+
+       return 0;
+error:
+       remove_source_entry(entry);
+       return err;
+}
+
 static int open_ctl(const char *name, snd_ctl_t **ctlp)
 {
        snd_ctl_t *ctl;
@@ -222,6 +285,7 @@ static void clear_dispatcher(int epfd, snd_ctl_t **ctls, int ncards)
 
 int monitor(const char *name)
 {
+       LIST_HEAD(srcs);
        snd_ctl_t *ctls[MAX_CARDS] = {0};
        int ncards = 0;
        int show_cards;
@@ -240,6 +304,9 @@ int monitor(const char *name)
                snd_card_iterator_init(&iter);
                while ((cardname = snd_card_iterator_next(&iter))) {
                        err = open_ctl(cardname, &ctls[ncards]);
+                       if (err < 0)
+                               goto error;
+                       err = insert_source_entry(&srcs, ctls[ncards], cardname);
                        if (err < 0)
                                goto error;
                        ncards++;
@@ -247,6 +314,9 @@ int monitor(const char *name)
                show_cards = 1;
        } else {
                err = open_ctl(name, &ctls[0]);
+               if (err < 0)
+                       goto error;
+               err = insert_source_entry(&srcs, ctls[ncards], name);
                if (err < 0)
                        goto error;
                ncards++;
@@ -259,6 +329,7 @@ int monitor(const char *name)
        clear_dispatcher(epfd, ctls, ncards);
 
 error:
+       clear_source_list(&srcs);
        for (i = 0; i < ncards; i++) {
                if (ctls[i])
                        snd_ctl_close(ctls[i]);