All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: Sergey <sergemp@mail.ru>
Cc: alsa-devel@alsa-project.org
Subject: Re: [PATCH] alsa-plugins: fix polling and recovering in alsa-jack plugin
Date: Mon, 05 May 2014 17:56:27 +0200	[thread overview]
Message-ID: <s5hzjiwdxsk.wl%tiwai@suse.de> (raw)
In-Reply-To: <1399056393.47049129@f181.i.mail.ru>

At Fri, 02 May 2014 22:46:33 +0400,
Sergey wrote:
> 
> Hello.
> 
> This patch fixes polling in alsa-to-jack plugin.
> It makes poll()+_poll_revents() return correct values
> whenever there's something to read/write.
> 
> Additionally jack_deactivate() code makes it survive snd_pcm_recover().
> 
> It works for the code example I posted before, aplay, arecord, mozilla, etc.
> 
> Comments and suggestions are welcome.

Thanks for the patch.  The basic idea looks good, but some suggestions
below.

> 
> ---
> diff --git a/jack/pcm_jack.c b/jack/pcm_jack.c
> index 7a8b24d..a39fea5 100644
> --- a/jack/pcm_jack.c
> +++ b/jack/pcm_jack.c
> @@ -42,6 +42,7 @@ typedef struct {
>  	unsigned int num_ports;
>  	unsigned int hw_ptr;
>  	unsigned int sample_bits;
> +	snd_pcm_uframes_t min_avail;
>  
>  	unsigned int channels;
>  	snd_pcm_channel_area_t *areas;
> @@ -50,6 +51,41 @@ typedef struct {
>  	jack_client_t *client;
>  } snd_pcm_jack_t;
>  
> +static inline int poll_blocked(snd_pcm_ioplug_t *io)

You don't need inline in general.  Compilers should be smart enough
nowadays.

> +{
> +	static char buf[65536];
> +	snd_pcm_sframes_t avail;
> +	snd_pcm_jack_t *jack = io->private_data;
> +
> +	if (io->state == SND_PCM_STATE_RUNNING)
> +	{

Please follow the coding style in that file.  The brace is placed in
the same line as if ().

> +		avail = snd_pcm_avail_update(io->pcm);
> +		if (avail >= 0 && avail < jack->min_avail)
> +		{
> +			read(io->poll_fd, &buf, sizeof buf);

So, it's intended to clear all pending writes, right?
If so, do reads in loop.  Then you don't have to use such a big
buffer.  The size of 32 or such should be enough.

> +			return 1;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static inline int poll_unblocked(snd_pcm_ioplug_t *io)

The function names are a bit too ambiguous and hard to understand what
they are really doing only from the names.

> +{
> +	static char buf[1];
> +	snd_pcm_sframes_t avail;
> +	snd_pcm_jack_t *jack = io->private_data;
> +
> +	avail = snd_pcm_avail_update(io->pcm);
> +	if (avail < 0 || avail >= jack->min_avail)
> +	{
> +		write(jack->fd, &buf, 1);
> +		return 1;
> +	}
> +
> +	return 0;
> +}
> +
>  static void snd_pcm_jack_free(snd_pcm_jack_t *jack)
>  {
>  	if (jack) {
> @@ -81,14 +117,10 @@ static int snd_pcm_jack_poll_revents(snd_pcm_ioplug_t *io,
>  				     struct pollfd *pfds, unsigned int nfds,
>  				     unsigned short *revents)
>  {
> -	static char buf[1];
> -	
>  	assert(pfds && nfds == 1 && revents);
>  
> -	read(pfds[0].fd, buf, 1);
> -
>  	*revents = pfds[0].revents & ~(POLLIN | POLLOUT);
> -	if (pfds[0].revents & POLLIN)
> +	if (pfds[0].revents & POLLIN && !poll_blocked(io))
>  		*revents |= (io->stream == SND_PCM_STREAM_PLAYBACK) ? POLLOUT : POLLIN;
>  	return 0;
>  }
> @@ -105,7 +137,6 @@ snd_pcm_jack_process_cb(jack_nframes_t nframes, snd_pcm_ioplug_t *io)
>  	snd_pcm_jack_t *jack = io->private_data;
>  	const snd_pcm_channel_area_t *areas;
>  	snd_pcm_uframes_t xfer = 0;
> -	static char buf[1];
>  	unsigned int channel;
>  	
>  	for (channel = 0; channel < io->channels; channel++) {
> @@ -145,7 +176,7 @@ snd_pcm_jack_process_cb(jack_nframes_t nframes, snd_pcm_ioplug_t *io)
>  		xfer += frames;
>  	}
>  
> -	write(jack->fd, buf, 1); /* for polling */
> +	poll_unblocked(io); /* unblock socket for polling if needed */
>  
>  	return 0;
>  }
> @@ -154,9 +185,25 @@ static int snd_pcm_jack_prepare(snd_pcm_ioplug_t *io)
>  {
>  	snd_pcm_jack_t *jack = io->private_data;
>  	unsigned int i;
> +	snd_pcm_sw_params_t *swparams;
> +	int err;
>  
>  	jack->hw_ptr = 0;
>  
> +	jack->min_avail = io->period_size;
> +	snd_pcm_sw_params_alloca(&swparams);
> +	err = snd_pcm_sw_params_current(io->pcm, swparams);
> +	if (err == 0) {
> +		snd_pcm_sw_params_get_avail_min(swparams, &jack->min_avail);
> +	}
> +
> +	poll_unblocked(io); /* unblock socket for initial polling if needed */

Is this really needed?

> +
> +	if (jack->activated) {
> +		jack_deactivate(jack->client);
> +		jack->activated = 0;
> +	}

This is same as just calling snd_pcm_jack_stop().


thanks,

Takashi

  reply	other threads:[~2014-05-05 15:56 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-02 18:46 [PATCH] alsa-plugins: fix polling and recovering in alsa-jack plugin Sergey
2014-05-05 15:56 ` Takashi Iwai [this message]
2014-05-09  0:00   ` Sergey
2014-05-09  5:34     ` Takashi Iwai
2014-05-12 23:20       ` Sergey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=s5hzjiwdxsk.wl%tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=alsa-devel@alsa-project.org \
    --cc=sergemp@mail.ru \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.