diff mbox series

[RFC,alsa-utils,5/9] alsactl: use link list to maintain source of events

Message ID 20181005144729.21388-6-o-takashi@sakamocchi.jp (mailing list archive)
State New, archived
Headers show
Series alsactl: monitor mode friendly for | expand

Commit Message

Takashi Sakamoto Oct. 5, 2018, 2:47 p.m. UTC
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(+)

Comments

Jaroslav Kysela Oct. 5, 2018, 5:14 p.m. UTC | #1
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]);
>
Takashi Sakamoto Oct. 7, 2018, 3:04 a.m. UTC | #2
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
Takashi Iwai Oct. 8, 2018, 3:06 p.m. UTC | #3
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
Jaroslav Kysela Oct. 8, 2018, 3:14 p.m. UTC | #4
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>
Takashi Sakamoto Oct. 9, 2018, 3:15 a.m. UTC | #5
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 mbox series

Patch

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]);