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;
if (err < 0) goto error; ncards++;err = insert_source_entry(&srcs, ctls[ncards], name);
@@ -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]);