From 131d6610fc7d101f711449c821de50915c55aaef Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Sun, 8 Feb 2004 10:19:52 +0000 Subject: [PATCH] Fixed file plugin - mmap access was broken and revents were not handled correctly --- src/pcm/pcm.c | 2 ++ src/pcm/pcm_file.c | 53 +++++++++++++++++++++++++++++++++++---------- src/pcm/pcm_local.h | 6 ++--- src/pcm/pcm_mmap.c | 4 ++-- src/pcm/pcm_plug.c | 4 ++-- 5 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 272c9541..9ddfbd8a 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -2257,6 +2257,8 @@ int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t char *dst; int width; int src_step, dst_step; + if (dst_area == src_area && dst_offset == src_offset) + return 0; if (!src_area->addr) return snd_pcm_area_silence(dst_area, dst_offset, samples, format); src = snd_pcm_channel_area_addr(src_area, src_offset); diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c index 4dfa1140..81b2704d 100644 --- a/src/pcm/pcm_file.c +++ b/src/pcm/pcm_file.c @@ -138,6 +138,12 @@ static int snd_pcm_file_async(snd_pcm_t *pcm, int sig, pid_t pid) return snd_pcm_async(file->slave, sig, pid); } +static int snd_pcm_file_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents) +{ + snd_pcm_file_t *file = pcm->private_data; + return snd_pcm_poll_descriptors_revents(file->slave, pfds, nfds, revents); +} + static int snd_pcm_file_info(snd_pcm_t *pcm, snd_pcm_info_t * info) { snd_pcm_file_t *file = pcm->private_data; @@ -345,6 +351,19 @@ static int snd_pcm_file_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) return snd_pcm_hw_refine(file->slave, params); } +static int snd_pcm_file_hw_free(snd_pcm_t *pcm) +{ + snd_pcm_file_t *file = pcm->private_data; + if (file->wbuf) { + free(file->wbuf); + if (file->wbuf_areas) + free(file->wbuf_areas); + file->wbuf = 0; + file->wbuf_areas = 0; + } + return snd_pcm_hw_free(file->slave); +} + static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params) { snd_pcm_file_t *file = pcm->private_data; @@ -358,7 +377,15 @@ static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params) file->wbuf_size_bytes = snd_pcm_frames_to_bytes(slave, file->wbuf_size); assert(!file->wbuf); file->wbuf = malloc(file->wbuf_size_bytes); + if (file->wbuf == NULL) { + snd_pcm_file_hw_free(pcm); + return -ENOMEM; + } file->wbuf_areas = malloc(sizeof(*file->wbuf_areas) * slave->channels); + if (file->wbuf_areas == NULL) { + snd_pcm_file_hw_free(pcm); + return -ENOMEM; + } file->appl_ptr = file->file_ptr_bytes = 0; for (channel = 0; channel < slave->channels; ++channel) { snd_pcm_channel_area_t *a = &file->wbuf_areas[channel]; @@ -369,18 +396,6 @@ static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params) return 0; } -static int snd_pcm_file_hw_free(snd_pcm_t *pcm) -{ - snd_pcm_file_t *file = pcm->private_data; - if (file->wbuf) { - free(file->wbuf); - free(file->wbuf_areas); - file->wbuf = 0; - file->wbuf_areas = 0; - } - return snd_pcm_hw_free(file->slave); -} - static int snd_pcm_file_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params) { snd_pcm_file_t *file = pcm->private_data; @@ -389,11 +404,23 @@ static int snd_pcm_file_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params) static int snd_pcm_file_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED) { + snd_pcm_file_t *file = pcm->private_data; + snd_pcm_t *slave = file->slave; + pcm->running_areas = slave->running_areas; + pcm->stopped_areas = slave->stopped_areas; + pcm->mmap_channels = slave->mmap_channels; + pcm->mmap_shadow = 1; return 0; } static int snd_pcm_file_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED) { + snd_pcm_file_t *file = pcm->private_data; + snd_pcm_t *slave = file->slave; + pcm->mmap_channels = NULL; + pcm->running_areas = NULL; + pcm->stopped_areas = NULL; + pcm->mmap_shadow = 0; return 0; } @@ -423,6 +450,7 @@ static snd_pcm_ops_t snd_pcm_file_ops = { .dump = snd_pcm_file_dump, .nonblock = snd_pcm_file_nonblock, .async = snd_pcm_file_async, + .poll_revents = snd_pcm_file_poll_revents, .mmap = snd_pcm_file_mmap, .munmap = snd_pcm_file_munmap, }; @@ -512,6 +540,7 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name, pcm->private_data = file; pcm->poll_fd = slave->poll_fd; pcm->poll_events = slave->poll_events; + pcm->mmap_shadow = 1; snd_pcm_link_hw_ptr(pcm, slave); snd_pcm_link_appl_ptr(pcm, slave); *pcmp = pcm; diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index e5ecb90c..f01f7a00 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -200,9 +200,9 @@ struct _snd_pcm { snd_pcm_rbptr_t appl; snd_pcm_rbptr_t hw; snd_pcm_uframes_t min_align; - int mmap_rw; - int shadow_mmap; - int donot_close; + int mmap_rw: 1, + mmap_shadow: 1, + donot_close: 1; snd_pcm_channel_info_t *mmap_channels; snd_pcm_channel_area_t *running_areas; snd_pcm_channel_area_t *stopped_areas; diff --git a/src/pcm/pcm_mmap.c b/src/pcm/pcm_mmap.c index dd30f5c7..6cf1ff1a 100644 --- a/src/pcm/pcm_mmap.c +++ b/src/pcm/pcm_mmap.c @@ -295,7 +295,7 @@ int snd_pcm_mmap(snd_pcm_t *pcm) err = pcm->ops->mmap(pcm); if (err < 0) return err; - if (pcm->shadow_mmap) + if (pcm->mmap_shadow) return 0; pcm->mmap_channels = calloc(pcm->channels, sizeof(pcm->mmap_channels[0])); if (!pcm->mmap_channels) @@ -434,7 +434,7 @@ int snd_pcm_munmap(snd_pcm_t *pcm) unsigned int c; assert(pcm); assert(pcm->mmap_channels); - if (pcm->shadow_mmap) + if (pcm->mmap_shadow) return pcm->ops->munmap(pcm); for (c = 0; c < pcm->channels; ++c) { snd_pcm_channel_info_t *i = &pcm->mmap_channels[c]; diff --git a/src/pcm/pcm_plug.c b/src/pcm/pcm_plug.c index b3f43b9d..bfca32bb 100644 --- a/src/pcm/pcm_plug.c +++ b/src/pcm/pcm_plug.c @@ -943,7 +943,7 @@ static int snd_pcm_plug_mmap(snd_pcm_t *pcm) pcm->mmap_channels = plug->slave->mmap_channels; pcm->running_areas = plug->slave->running_areas; pcm->stopped_areas = plug->slave->stopped_areas; - pcm->shadow_mmap = 1; + pcm->mmap_shadow = 1; return 0; } @@ -953,7 +953,7 @@ static int snd_pcm_plug_munmap(snd_pcm_t *pcm) pcm->mmap_channels = NULL; pcm->running_areas = NULL; pcm->stopped_areas = NULL; - pcm->shadow_mmap = 0; + pcm->mmap_shadow = 0; return 0; } -- 2.47.1