Dne 5.10.2018 v 16:47 Takashi Sakamoto napsal(a): > 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. Thanks for the improved code. Please, use macros in list.h to manage linked list which are inherited from the kernel here. Jaroslav > > Signed-off-by: Takashi Sakamoto <o-takashi@xxxxxxxxxxxxx> > --- > alsactl/monitor.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 84 insertions(+) > > diff --git a/alsactl/monitor.c b/alsactl/monitor.c > index cf5c50a..8b16307 100644 > --- a/alsactl/monitor.c > +++ b/alsactl/monitor.c > @@ -29,6 +29,16 @@ > static int signal_type; > static bool interrupted; > > +struct src_entry { > + snd_ctl_t *handle; > + char *name; > + unsigned int pfd_count; > + struct { > + struct src_entry *prev; > + struct src_entry *next; > + } list; > +}; > + > #define MAX_CARDS 256 > > struct snd_card_iterator { > @@ -59,6 +69,72 @@ static const char *snd_card_iterator_next(struct snd_card_iterator *iter) > return (const char *)iter->name; > } > > +static inline void remove_source_entry(struct src_entry *src) > +{ > + struct src_entry *prev = src->list.prev; > + struct src_entry *next = src->list.next; > + > + if (prev) > + prev->list.next = src->list.next; > + if (next) > + next->list.prev = src->list.prev; > + free(src->name); > + free(src); > +} > + > +static void clear_source_list(struct src_entry **srcs) > +{ > + while (*srcs) { > + struct src_entry *src = *srcs; > + *srcs = src->list.next; > + > + remove_source_entry(src); > + } > +} > + > +static int insert_source_entry(struct src_entry **head, snd_ctl_t *handle, > + const char *name) > +{ > + struct src_entry *src; > + int count; > + int err; > + > + src = calloc(1, sizeof(*src)); > + if (!src) > + return -ENOMEM; > + src->handle = handle; > + > + src->name = strdup(name); > + if (!src->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; > + } > + src->pfd_count = count; > + > + if (*head) { > + src->list.next = (*head)->list.next; > + src->list.prev = *head; > + (*head)->list.next = src; > + } else { > + *head = src; > + } > + > + return 0; > +error: > + free(src); > + return err; > +} > + > static int open_ctl(const char *name, snd_ctl_t **ctlp) > { > snd_ctl_t *ctl; > @@ -259,6 +335,7 @@ static int prepare_signal_handler(void) > > int monitor(const char *name) > { > + struct src_entry *srcs = NULL; > snd_ctl_t *ctls[MAX_CARDS] = {0}; > int ncards = 0; > int show_cards; > @@ -281,6 +358,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; > @@ -288,6 +368,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++; > @@ -300,6 +383,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]); > -- Jaroslav Kysela <perex@xxxxxxxx> Linux Sound Maintainer; ALSA Project; Red Hat, Inc. _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel