[alsa-devel] [PATCH v2 1/1] ALSA: seq: Continue broadcasting events to ports if one of them fails
Takashi Iwai
tiwai at suse.de
Wed Jun 4 17:31:47 CEST 2014
At Wed, 4 Jun 2014 11:20:55 -0400,
Adam Goode wrote:
>
> Sometimes PORT_EXIT messages are lost when a process is exiting.
> This happens if you subscribe to the announce port with client A,
> then subscribe to the announce port with client B, then kill client A.
> Client B will not see the PORT_EXIT message because client A's port is
> closing and is earlier in the announce port subscription list. The
> for each loop will try to send the announcement to client A and fail,
> then will stop trying to broadcast to other ports. Killing B works fine
> since the announcement will already have gone to A. The CLIENT_EXIT
> message does not get lost.
>
> How to reproduce problem:
>
> *** termA
> $ aseqdump -p 0:1
> 0:1 Port subscribed 0:1 -> 128:0
>
> *** termB
> $ aseqdump -p 0:1
>
> *** termA
> 0:1 Client start client 129
> 0:1 Port start 129:0
> 0:1 Port subscribed 0:1 -> 129:0
>
> *** termB
> 0:1 Port subscribed 0:1 -> 129:0
>
> *** termA
> ^C
>
> *** termB
> 0:1 Client exit client 128
> <--- expected Port exit as well (before client exit)
>
> Signed-off-by: Adam Goode <agoode at google.com>
Applied, thanks.
Takashi
>
> diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
> index 9ca5e64..225c7315 100644
> --- a/sound/core/seq/seq_clientmgr.c
> +++ b/sound/core/seq/seq_clientmgr.c
> @@ -660,7 +660,7 @@ static int deliver_to_subscribers(struct snd_seq_client *client,
> int atomic, int hop)
> {
> struct snd_seq_subscribers *subs;
> - int err = 0, num_ev = 0;
> + int err, result = 0, num_ev = 0;
> struct snd_seq_event event_saved;
> struct snd_seq_client_port *src_port;
> struct snd_seq_port_subs_info *grp;
> @@ -685,8 +685,12 @@ static int deliver_to_subscribers(struct snd_seq_client *client,
> subs->info.flags & SNDRV_SEQ_PORT_SUBS_TIME_REAL);
> err = snd_seq_deliver_single_event(client, event,
> 0, atomic, hop);
> - if (err < 0)
> - break;
> + if (err < 0) {
> + /* save first error that occurs and continue */
> + if (!result)
> + result = err;
> + continue;
> + }
> num_ev++;
> /* restore original event record */
> *event = event_saved;
> @@ -697,7 +701,7 @@ static int deliver_to_subscribers(struct snd_seq_client *client,
> up_read(&grp->list_mutex);
> *event = event_saved; /* restore */
> snd_seq_port_unlock(src_port);
> - return (err < 0) ? err : num_ev;
> + return (result < 0) ? result : num_ev;
> }
>
>
> @@ -709,7 +713,7 @@ static int port_broadcast_event(struct snd_seq_client *client,
> struct snd_seq_event *event,
> int atomic, int hop)
> {
> - int num_ev = 0, err = 0;
> + int num_ev = 0, err, result = 0;
> struct snd_seq_client *dest_client;
> struct snd_seq_client_port *port;
>
> @@ -724,14 +728,18 @@ static int port_broadcast_event(struct snd_seq_client *client,
> err = snd_seq_deliver_single_event(NULL, event,
> SNDRV_SEQ_FILTER_BROADCAST,
> atomic, hop);
> - if (err < 0)
> - break;
> + if (err < 0) {
> + /* save first error that occurs and continue */
> + if (!result)
> + result = err;
> + continue;
> + }
> num_ev++;
> }
> read_unlock(&dest_client->ports_lock);
> snd_seq_client_unlock(dest_client);
> event->dest.port = SNDRV_SEQ_ADDRESS_BROADCAST; /* restore */
> - return (err < 0) ? err : num_ev;
> + return (result < 0) ? result : num_ev;
> }
>
> /*
> @@ -741,7 +749,7 @@ static int port_broadcast_event(struct snd_seq_client *client,
> static int broadcast_event(struct snd_seq_client *client,
> struct snd_seq_event *event, int atomic, int hop)
> {
> - int err = 0, num_ev = 0;
> + int err, result = 0, num_ev = 0;
> int dest;
> struct snd_seq_addr addr;
>
> @@ -760,12 +768,16 @@ static int broadcast_event(struct snd_seq_client *client,
> err = snd_seq_deliver_single_event(NULL, event,
> SNDRV_SEQ_FILTER_BROADCAST,
> atomic, hop);
> - if (err < 0)
> - break;
> + if (err < 0) {
> + /* save first error that occurs and continue */
> + if (!result)
> + result = err;
> + continue;
> + }
> num_ev += err;
> }
> event->dest = addr; /* restore */
> - return (err < 0) ? err : num_ev;
> + return (result < 0) ? result : num_ev;
> }
>
>
> --
> 2.0.0.526.g5318336
>
More information about the Alsa-devel
mailing list