]> git.alsa-project.org Git - alsa-lib.git/commitdiff
pcm: dmix: Fix doubly resume of slave PCM
authorTakashi Iwai <tiwai@suse.de>
Wed, 11 May 2016 11:06:25 +0000 (13:06 +0200)
committerTakashi Iwai <tiwai@suse.de>
Wed, 11 May 2016 11:06:25 +0000 (13:06 +0200)
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>
src/pcm/pcm_direct.c

index e28738b0de96d3ed1d6b2c35bd402706c12fac78..ac082f1a73b236a66cb9fe62091b8735edd4cea4 100644 (file)
@@ -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;