Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 2642
b: refs/heads/master
c: 21cb2a2
h: refs/heads/master
v: v3
  • Loading branch information
Takashi Iwai authored and Jaroslav Kysela committed Jun 22, 2005
1 parent 0310261 commit 72d2cac
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 35 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ce43fbaececc82196d321671159483b3287de128
refs/heads/master: 21cb2a2ec5818cbba01bcb7f24388670322c77f9
70 changes: 36 additions & 34 deletions trunk/sound/core/pcm_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -1368,43 +1368,32 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream)
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;

down_read(&snd_pcm_link_rwsem);
snd_power_lock(card);
if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
result = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile);
if (result < 0)
goto _unlock;
if (result < 0) {
snd_power_unlock(card);
return result;
}
}

/* allocate temporary record for drain sync */
down_read(&snd_pcm_link_rwsem);
if (snd_pcm_stream_linked(substream)) {
drec = kmalloc(substream->group->count * sizeof(*drec), GFP_KERNEL);
if (! drec) {
result = -ENOMEM;
goto _unlock;
up_read(&snd_pcm_link_rwsem);
snd_power_unlock(card);
return -ENOMEM;
}
} else
drec = &drec_tmp;

snd_pcm_stream_lock_irq(substream);
/* resume pause */
if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
snd_pcm_pause(substream, 0);

/* pre-start/stop - all running streams are changed to DRAINING state */
result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0);
if (result < 0)
goto _end;

/* check streams with PLAYBACK & DRAINING */
/* count only playback streams */
num_drecs = 0;
snd_pcm_group_for_each(pos, substream) {
snd_pcm_substream_t *s = snd_pcm_group_substream_entry(pos);
runtime = s->runtime;
if (runtime->status->state != SNDRV_PCM_STATE_DRAINING) {
runtime->status->state = SNDRV_PCM_STATE_SETUP;
continue;
}
if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
d = &drec[num_drecs++];
d->substream = s;
Expand All @@ -1418,16 +1407,37 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream)
runtime->stop_threshold = runtime->buffer_size;
}
}

up_read(&snd_pcm_link_rwsem);
if (! num_drecs)
goto _end;
goto _error;

snd_pcm_stream_lock_irq(substream);
/* resume pause */
if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
snd_pcm_pause(substream, 0);

/* pre-start/stop - all running streams are changed to DRAINING state */
result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0);
if (result < 0) {
snd_pcm_stream_unlock_irq(substream);
goto _error;
}

for (;;) {
long tout;
if (signal_pending(current)) {
result = -ERESTARTSYS;
break;
}
/* all finished? */
for (i = 0; i < num_drecs; i++) {
runtime = drec[i].substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_DRAINING)
break;
}
if (i == num_drecs)
break; /* yes, all drained */

set_current_state(TASK_INTERRUPTIBLE);
snd_pcm_stream_unlock_irq(substream);
snd_power_unlock(card);
Expand All @@ -1444,29 +1454,21 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream)
}
break;
}
/* all finished? */
for (i = 0; i < num_drecs; i++) {
runtime = drec[i].substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_DRAINING)
break;
}
if (i == num_drecs)
break;
}

snd_pcm_stream_unlock_irq(substream);

_error:
for (i = 0; i < num_drecs; i++) {
d = &drec[i];
runtime = d->substream->runtime;
remove_wait_queue(&runtime->sleep, &d->wait);
runtime->stop_threshold = d->stop_threshold;
}

_end:
snd_pcm_stream_unlock_irq(substream);
if (drec != &drec_tmp)
kfree(drec);
_unlock:
snd_power_unlock(card);
up_read(&snd_pcm_link_rwsem);

return result;
}
Expand Down

0 comments on commit 72d2cac

Please sign in to comment.