summaryrefslogtreecommitdiff
path: root/src/pcm/pcm_direct.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2016-05-11 13:06:25 +0200
committerTakashi Iwai <tiwai@suse.de>2016-05-11 13:06:25 +0200
commit5610b356b5f110f7f8e586f56e5b74e0f0c2db38 (patch)
treefb88e2141f77a9dddc249eb4e6a8a252711fb612 /src/pcm/pcm_direct.c
parentc14b0a08f0bf58e4f62307c68f8ff0137b4dec19 (diff)
downloadalsa-lib-5610b356b5f110f7f8e586f56e5b74e0f0c2db38.tar.gz
pcm: dmix: Fix doubly resume of slave PCM
The dmix plugin and co may trigger the resume for each instance in snd_pcm_direct_resume(). It means that the slave PCM gets resumed or re-prepared/started by each opened dmix stream, and this may end up with the doubly triggers even though the slave PCM has been already resumed by another dmix stream. For avoiding this conflicts, check the slave PCM state and resume only when it's still in the suspended state. Meanwhile we keep the shadow state updated no matter whether the slave was triggered or not. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'src/pcm/pcm_direct.c')
-rw-r--r--src/pcm/pcm_direct.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
index e28738b0..ac082f1a 100644
--- a/src/pcm/pcm_direct.c
+++ b/src/pcm/pcm_direct.c
@@ -841,6 +841,12 @@ int snd_pcm_direct_resume(snd_pcm_t *pcm)
int err;
snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
+ /* resume only when the slave PCM is still in suspended state */
+ if (snd_pcm_state(dmix->spcm) != SND_PCM_STATE_SUSPENDED) {
+ err = 0;
+ goto out;
+ }
+
err = snd_pcm_resume(dmix->spcm);
if (err == -ENOSYS) {
/* FIXME: error handling? */
@@ -848,6 +854,7 @@ int snd_pcm_direct_resume(snd_pcm_t *pcm)
snd_pcm_start(dmix->spcm);
err = 0;
}
+ out:
dmix->state = snd_pcm_state(dmix->spcm);
snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
return err;