Message ID | 20181005144729.21388-6-o-takashi@sakamocchi.jp (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | alsactl: monitor mode friendly for | expand |
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@sakamocchi.jp> > --- > 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]); >
Hi Jaroslav, On Oct 6 2018 02:14, Jaroslav Kysela wrote: > 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. Let me confirm the macro about which you mention. This patchset is for alsa-utils. In a package of alsa-utils, there's no such header. A package of alsa-lib v1.1.6 has 'include/list.h', however this is not installation target. Would I ask you where the list is available? Thanks Takashi Sakamoto
On Sun, 07 Oct 2018 05:04:36 +0200, Takashi Sakamoto wrote: > > Hi Jaroslav, > > On Oct 6 2018 02:14, Jaroslav Kysela wrote: > > 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. > > Let me confirm the macro about which you mention. > > This patchset is for alsa-utils. In a package of alsa-utils, there's no > such header. > > A package of alsa-lib v1.1.6 has 'include/list.h', however this is not > installation target. > > Would I ask you where the list is available? It's fine to put a common list.h into alsa-utils/include. thanks, Takashi
Dne 7.10.2018 v 05:04 Takashi Sakamoto napsal(a): > Hi Jaroslav, > > On Oct 6 2018 02:14, Jaroslav Kysela wrote: >> 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. > > Let me confirm the macro about which you mention. > > This patchset is for alsa-utils. In a package of alsa-utils, there's no > such header. > > A package of alsa-lib v1.1.6 has 'include/list.h', however this is not > installation target. > > Would I ask you where the list is available? [alsa-utils]$ git log alsactl/list.h commit b402cf543aee5f6cd7561d964065a26f07459c8c Author: Jaroslav Kysela <perex@perex.cz> Date: Thu Jul 31 15:45:08 2008 +0200 Initial 'alsactl init' implementation See 'man 7 alsactl_init' for more details. Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Hi Jaroslav, On Oct 9 2018 00:14, Jaroslav Kysela wrote: > Dne 7.10.2018 v 05:04 Takashi Sakamoto napsal(a): >> Hi Jaroslav, >> >> On Oct 6 2018 02:14, Jaroslav Kysela wrote: >>> 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. >> >> Let me confirm the macro about which you mention. >> >> This patchset is for alsa-utils. In a package of alsa-utils, there's no >> such header. >> >> A package of alsa-lib v1.1.6 has 'include/list.h', however this is not >> installation target. >> >> Would I ask you where the list is available? > > [alsa-utils]$ git log alsactl/list.h > commit b402cf543aee5f6cd7561d964065a26f07459c8c > Author: Jaroslav Kysela <perex@perex.cz> > Date: Thu Jul 31 15:45:08 2008 +0200 > > Initial 'alsactl init' implementation > > See 'man 7 alsactl_init' for more details. > > Signed-off-by: Jaroslav Kysela <perex@perex.cz> Ah..., exactly. I overlooked this probability. I'll use it for next patchset. Thanks Takashi Sakamoto
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]);
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> --- alsactl/monitor.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+)