mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-31 22:25:35 -04:00
PCM: snd_pcm_xxxx_drain() maybe blocked after suspend and resume
After suspend and resume, the alsa driver is stopped. But if alsa-lib run into snd_pcm_xxxx_drain(), it need to wait avail >= pcm->stop_threshold, otherwise, it will not exit the loop, so finally it is blocked at poll() of snd_pcm_wait_nocheck(pcm, -1). This patch is to add state check after snd_pcm_wait_nocheck(pcm, -1), if the state is SND_PCM_STATE_SUSPENDED, then return error. Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
2fd098b587
commit
9ee6ec80b8
2 changed files with 28 additions and 0 deletions
|
|
@ -617,6 +617,13 @@ static int snd_pcm_dmix_drain(snd_pcm_t *pcm)
|
||||||
snd_pcm_uframes_t stop_threshold;
|
snd_pcm_uframes_t stop_threshold;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
switch (snd_pcm_state(dmix->spcm)) {
|
||||||
|
case SND_PCM_STATE_SUSPENDED:
|
||||||
|
return -ESTRPIPE;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (dmix->state == SND_PCM_STATE_OPEN)
|
if (dmix->state == SND_PCM_STATE_OPEN)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if (pcm->mode & SND_PCM_NONBLOCK)
|
if (pcm->mode & SND_PCM_NONBLOCK)
|
||||||
|
|
@ -649,6 +656,13 @@ static int snd_pcm_dmix_drain(snd_pcm_t *pcm)
|
||||||
snd_pcm_dmix_sync_area(pcm);
|
snd_pcm_dmix_sync_area(pcm);
|
||||||
snd_pcm_wait_nocheck(pcm, -1);
|
snd_pcm_wait_nocheck(pcm, -1);
|
||||||
snd_pcm_direct_clear_timer_queue(dmix); /* force poll to wait */
|
snd_pcm_direct_clear_timer_queue(dmix); /* force poll to wait */
|
||||||
|
|
||||||
|
switch (snd_pcm_state(dmix->spcm)) {
|
||||||
|
case SND_PCM_STATE_SUSPENDED:
|
||||||
|
return -ESTRPIPE;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (dmix->state == SND_PCM_STATE_DRAINING);
|
} while (dmix->state == SND_PCM_STATE_DRAINING);
|
||||||
pcm->stop_threshold = stop_threshold;
|
pcm->stop_threshold = stop_threshold;
|
||||||
|
|
|
||||||
|
|
@ -368,6 +368,13 @@ static int snd_pcm_dshare_drain(snd_pcm_t *pcm)
|
||||||
snd_pcm_uframes_t stop_threshold;
|
snd_pcm_uframes_t stop_threshold;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
switch (snd_pcm_state(dshare->spcm)) {
|
||||||
|
case SND_PCM_STATE_SUSPENDED:
|
||||||
|
return -ESTRPIPE;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (dshare->state == SND_PCM_STATE_OPEN)
|
if (dshare->state == SND_PCM_STATE_OPEN)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if (pcm->mode & SND_PCM_NONBLOCK)
|
if (pcm->mode & SND_PCM_NONBLOCK)
|
||||||
|
|
@ -400,6 +407,13 @@ static int snd_pcm_dshare_drain(snd_pcm_t *pcm)
|
||||||
snd_pcm_dshare_sync_area(pcm);
|
snd_pcm_dshare_sync_area(pcm);
|
||||||
snd_pcm_wait_nocheck(pcm, -1);
|
snd_pcm_wait_nocheck(pcm, -1);
|
||||||
snd_pcm_direct_clear_timer_queue(dshare); /* force poll to wait */
|
snd_pcm_direct_clear_timer_queue(dshare); /* force poll to wait */
|
||||||
|
|
||||||
|
switch (snd_pcm_state(dshare->spcm)) {
|
||||||
|
case SND_PCM_STATE_SUSPENDED:
|
||||||
|
return -ESTRPIPE;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (dshare->state == SND_PCM_STATE_DRAINING);
|
} while (dshare->state == SND_PCM_STATE_DRAINING);
|
||||||
pcm->stop_threshold = stop_threshold;
|
pcm->stop_threshold = stop_threshold;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue