From b9dbee694a94a724670b36f4df1aeceb0dd4a261 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Wed, 3 Mar 2010 10:58:53 +0100 Subject: [PATCH] pcm direct plugins: drain() call might be blocked when threads are used Add SETUP state checks and do modifications according latest ALSA driver (passing wrong event identification). ALSA bug#4914 Signed-off-by: Jaroslav Kysela --- src/pcm/pcm_direct.c | 21 ++++++++++++++------- src/pcm/pcm_direct.h | 7 +++---- src/pcm/pcm_dmix.c | 2 +- src/pcm/pcm_dshare.c | 2 +- src/pcm/pcm_dsnoop.c | 2 +- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c index b648f3a9..0a9047dd 100644 --- a/src/pcm/pcm_direct.c +++ b/src/pcm/pcm_direct.c @@ -540,7 +540,6 @@ void snd_pcm_direct_clear_timer_queue(snd_pcm_direct_t *dmix) int snd_pcm_direct_timer_stop(snd_pcm_direct_t *dmix) { snd_timer_stop(dmix->timer); - snd_pcm_direct_clear_timer_queue(dmix); return 0; } @@ -567,6 +566,7 @@ int snd_pcm_direct_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned in switch (snd_pcm_state(dmix->spcm)) { case SND_PCM_STATE_XRUN: case SND_PCM_STATE_SUSPENDED: + case SND_PCM_STATE_SETUP: events |= POLLERR; break; default: @@ -577,6 +577,7 @@ int snd_pcm_direct_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned in switch (snd_pcm_state(pcm)) { case SND_PCM_STATE_XRUN: case SND_PCM_STATE_SUSPENDED: + case SND_PCM_STATE_SETUP: events |= POLLERR; break; default: @@ -1126,8 +1127,9 @@ int snd_pcm_direct_initialize_poll_fd(snd_pcm_direct_t *dmix) snd_timer_poll_descriptors(dmix->timer, &dmix->timer_fd, 1); dmix->poll_fd = dmix->timer_fd.fd; - dmix->timer_event_suspend = 1<timer_event_resume = 1<timer_events = (1<timer_event_suspend = 1<timer_event_resume = 1<timer_events &= ~((1<timer_events |= (1<timer_events |= 1<tread) { filter = (1<timer_event_suspend | - dmix->timer_event_resume; + dmix->timer_events; snd_timer_params_set_filter(params, filter); } ret = snd_timer_params(dmix->timer, params); diff --git a/src/pcm/pcm_direct.h b/src/pcm/pcm_direct.h index 006617a5..132c281c 100644 --- a/src/pcm/pcm_direct.h +++ b/src/pcm/pcm_direct.h @@ -142,10 +142,9 @@ struct snd_pcm_direct { int hw_fd; /* hardware file descriptor */ struct pollfd timer_fd; int poll_fd; - int tread; - int timer_need_poll; - unsigned int timer_event_suspend; - unsigned int timer_event_resume; + int tread: 1; + int timer_need_poll: 1; + unsigned int timer_events; int server_fd; pid_t server_pid; snd_timer_t *timer; /* timer used as poll_fd */ diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c index 3b791c15..cb62de92 100644 --- a/src/pcm/pcm_dmix.c +++ b/src/pcm/pcm_dmix.c @@ -605,8 +605,8 @@ static int snd_pcm_dmix_drop(snd_pcm_t *pcm) snd_pcm_direct_t *dmix = pcm->private_data; if (dmix->state == SND_PCM_STATE_OPEN) return -EBADFD; - snd_pcm_direct_timer_stop(dmix); dmix->state = SND_PCM_STATE_SETUP; + snd_pcm_direct_timer_stop(dmix); return 0; } diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c index c91fa3b1..02782a78 100644 --- a/src/pcm/pcm_dshare.c +++ b/src/pcm/pcm_dshare.c @@ -355,9 +355,9 @@ static int snd_pcm_dshare_drop(snd_pcm_t *pcm) snd_pcm_direct_t *dshare = pcm->private_data; if (dshare->state == SND_PCM_STATE_OPEN) return -EBADFD; + dshare->state = SND_PCM_STATE_SETUP; snd_pcm_direct_timer_stop(dshare); do_silence(pcm); - dshare->state = SND_PCM_STATE_SETUP; return 0; } diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c index 9d42c123..15c727a5 100644 --- a/src/pcm/pcm_dsnoop.c +++ b/src/pcm/pcm_dsnoop.c @@ -280,8 +280,8 @@ static int snd_pcm_dsnoop_drop(snd_pcm_t *pcm) snd_pcm_direct_t *dsnoop = pcm->private_data; if (dsnoop->state == SND_PCM_STATE_OPEN) return -EBADFD; - snd_timer_stop(dsnoop->timer); dsnoop->state = SND_PCM_STATE_SETUP; + snd_timer_stop(dsnoop->timer); return 0; } -- 2.47.1