[pulseaudio-discuss] [PATCH v2] alsa: Check return value of snd_pcm_mmap_commit()

David Henningsson david.henningsson at canonical.com
Fri Nov 14 02:27:44 PST 2014



On 2014-11-13 10:48, Peter Meerwald wrote:
> From: Peter Meerwald <p.meerwald at bct-electronic.com>
>
> snd_pcm_mmap_commit() actually transfers the memory area prepared by snd_pcm_mmap_begin(),
> it returns the 'count of transferred frames' which should be equal to the number of frames
> returned by snd_pcm_mmap_begin()
>
> however, this identify is not checked and the number of frames prepared are accounted for,
> not the number of frames commited -- this is wrong; the ALSA example codes bothers to
> check snd_pcm_mmap_commit()'s returned number of frames
>
> this patch just outputs a warning when sframes != frames -- let's see if it ever happens

It also seems to do refactoring?

>
> v2: (thanks David Henningson)
> * just log, no functional change as in v1
> * fix typos, fix subject
>
> Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>
> ---
>   src/modules/alsa/alsa-sink.c   |   11 +++++++++--
>   src/modules/alsa/alsa-source.c |   17 +++++++++++++----
>   2 files changed, 22 insertions(+), 6 deletions(-)
>
> diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
> index e256bbd..35f013c 100644
> --- a/src/modules/alsa/alsa-sink.c
> +++ b/src/modules/alsa/alsa-sink.c
> @@ -639,8 +639,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, bool polled, bo
>
>               p = (uint8_t*) areas[0].addr + (offset * u->frame_size);
>
> -            written = frames * u->frame_size;
> -            chunk.memblock = pa_memblock_new_fixed(u->core->mempool, p, written, true);
> +            chunk.memblock = pa_memblock_new_fixed(u->core->mempool, p, frames * u->frame_size, true);
>               chunk.length = pa_memblock_get_length(chunk.memblock);
>               chunk.index = 0;
>
> @@ -660,6 +659,14 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, bool polled, bo
>
>               work_done = true;
>
> +            if (PA_UNLIKELY((snd_pcm_uframes_t) sframes != frames)) {
> +                PA_ONCE_BEGIN {
> +                    pa_log_warn("ALSA mmap write was set up for %lu frames, but unexpectedly commited %lu frames.\n",
> +                        (unsigned long) frames, (unsigned long) sframes);
> +                } PA_ONCE_END;
> +            }
> +
> +            written = frames * u->frame_size;
>               u->write_count += written;
>               u->since_start += written;
>
> diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
> index 111c517..97d0d22 100644
> --- a/src/modules/alsa/alsa-source.c
> +++ b/src/modules/alsa/alsa-source.c
> @@ -562,6 +562,7 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, bool polled, boo
>               const snd_pcm_channel_area_t *areas;
>               snd_pcm_uframes_t offset, frames;
>               snd_pcm_sframes_t sframes;
> +            size_t got;
>
>               frames = (snd_pcm_uframes_t) (n_bytes / u->frame_size);
>   /*             pa_log_debug("%lu frames to read", (unsigned long) frames); */
> @@ -613,16 +614,24 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, bool polled, boo
>
>               work_done = true;
>
> -            u->read_count += frames * u->frame_size;
> +            if (PA_UNLIKELY((snd_pcm_uframes_t) sframes != frames)) {
> +                PA_ONCE_BEGIN {
> +                    pa_log_warn("ALSA mmap read was set up for %lu frames, but unexpectedly commited %lu frames.\n",
> +                        (unsigned long) frames, (unsigned long) sframes);
> +                } PA_ONCE_END;
> +            }
> +
> +            got = frames * u->frame_size;
> +            u->read_count += got;
>
>   #ifdef DEBUG_TIMING
> -            pa_log_debug("Read %lu bytes (of possible %lu bytes)", (unsigned long) (frames * u->frame_size), (unsigned long) n_bytes);
> +            pa_log_debug("Read %lu bytes (of possible %lu bytes)", (unsigned long) got, (unsigned long) n_bytes);
>   #endif
>
> -            if ((size_t) frames * u->frame_size >= n_bytes)
> +            if (got >= n_bytes)
>                   break;
>
> -            n_bytes -= (size_t) frames * u->frame_size;
> +            n_bytes -= got;
>           }
>       }
>
>

-- 
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic


More information about the pulseaudio-discuss mailing list