mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-11-09 13:30:03 -05:00
pcm: direct: Improved suspend/resume support
The current resume handling in PCM direct plugins don't treat multiple clients properly: once after the slave PCM gets resumed by one client, the access from others at a later point is seen as already running although the internal state isn't updated and becomes inconsistent. This may end up a negative size, which eventually hangs up. This patch is an attempt to improve the handling for resume. Now the suspended state is treated similarly like XRUN; namely, we keep the slave PCM "recoveries" count that is modified at each time the slave PCM XRUN happens, so that we can check the inconsistency against the client's state. As a differentiation to XRUN, we set the highest bit of recoveries count when the slave stream hits SUSPENDED state. This bit is referred at comparing with clients, and the client's state is updated to either XRUN or SUSPENDED depending on this bit. Along with this change, the actual resume is done in snd_pcm_direct_slave_recover(), and snd_pcm_direct_resume() rather calls this internally. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
29fbe34a0d
commit
b3ce9cb839
4 changed files with 52 additions and 38 deletions
|
|
@ -431,6 +431,7 @@ static int snd_pcm_dmix_sync_ptr(snd_pcm_t *pcm)
|
|||
dmix->state = SND_PCM_STATE_DISCONNECTED;
|
||||
return -ENODEV;
|
||||
case SND_PCM_STATE_XRUN:
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
if ((err = snd_pcm_direct_slave_recover(dmix)) < 0)
|
||||
return err;
|
||||
break;
|
||||
|
|
@ -457,11 +458,11 @@ static snd_pcm_state_t snd_pcm_dmix_state(snd_pcm_t *pcm)
|
|||
snd_pcm_state_t state;
|
||||
state = snd_pcm_state(dmix->spcm);
|
||||
switch (state) {
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
case SND_PCM_STATE_DISCONNECTED:
|
||||
dmix->state = state;
|
||||
return state;
|
||||
case SND_PCM_STATE_XRUN:
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
if ((err = snd_pcm_direct_slave_recover(dmix)) < 0)
|
||||
return err;
|
||||
break;
|
||||
|
|
@ -833,11 +834,10 @@ static snd_pcm_sframes_t snd_pcm_dmix_mmap_commit(snd_pcm_t *pcm,
|
|||
|
||||
switch (snd_pcm_state(dmix->spcm)) {
|
||||
case SND_PCM_STATE_XRUN:
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
if ((err = snd_pcm_direct_slave_recover(dmix)) < 0)
|
||||
return err;
|
||||
break;
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
return -ESTRPIPE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue