Commit 67641a81 authored by Jaroslav Kysela's avatar Jaroslav Kysela

ALSA CVS update - Takashi Iwai <tiwai@suse.de>

ALSA sequencer
- fixed the race conditions.
parent 04fa6b4f
...@@ -171,10 +171,12 @@ int snd_seq_fifo_cell_out(fifo_t *f, snd_seq_event_cell_t **cellp, int nonblock) ...@@ -171,10 +171,12 @@ int snd_seq_fifo_cell_out(fifo_t *f, snd_seq_event_cell_t **cellp, int nonblock)
{ {
snd_seq_event_cell_t *cell; snd_seq_event_cell_t *cell;
unsigned long flags; unsigned long flags;
wait_queue_t wait;
snd_assert(f != NULL, return -EINVAL); snd_assert(f != NULL, return -EINVAL);
*cellp = NULL; *cellp = NULL;
init_waitqueue_entry(&wait, current);
spin_lock_irqsave(&f->lock, flags); spin_lock_irqsave(&f->lock, flags);
while ((cell = fifo_cell_out(f)) == NULL) { while ((cell = fifo_cell_out(f)) == NULL) {
if (nonblock) { if (nonblock) {
...@@ -182,17 +184,19 @@ int snd_seq_fifo_cell_out(fifo_t *f, snd_seq_event_cell_t **cellp, int nonblock) ...@@ -182,17 +184,19 @@ int snd_seq_fifo_cell_out(fifo_t *f, snd_seq_event_cell_t **cellp, int nonblock)
spin_unlock_irqrestore(&f->lock, flags); spin_unlock_irqrestore(&f->lock, flags);
return -EAGAIN; return -EAGAIN;
} }
spin_unlock(&f->lock); set_current_state(TASK_INTERRUPTIBLE);
interruptible_sleep_on(&f->input_sleep); add_wait_queue(&f->input_sleep, &wait);
spin_lock(&f->lock); spin_unlock_irq(&f->lock);
schedule();
spin_lock_irq(&f->lock);
remove_wait_queue(&f->input_sleep, &wait);
if (signal_pending(current)) { if (signal_pending(current)) {
spin_unlock_irqrestore(&f->lock, flags); spin_unlock_irqrestore(&f->lock, flags);
return -ERESTARTSYS; return -ERESTARTSYS;
} }
} }
*cellp = cell;
spin_unlock_irqrestore(&f->lock, flags); spin_unlock_irqrestore(&f->lock, flags);
*cellp = cell;
return 0; return 0;
} }
......
...@@ -220,12 +220,14 @@ int snd_seq_cell_alloc(pool_t *pool, snd_seq_event_cell_t **cellp, int nonblock, ...@@ -220,12 +220,14 @@ int snd_seq_cell_alloc(pool_t *pool, snd_seq_event_cell_t **cellp, int nonblock,
snd_seq_event_cell_t *cell; snd_seq_event_cell_t *cell;
unsigned long flags; unsigned long flags;
int err = -EAGAIN; int err = -EAGAIN;
wait_queue_t wait;
if (pool == NULL) if (pool == NULL)
return -EINVAL; return -EINVAL;
*cellp = NULL; *cellp = NULL;
init_waitqueue_entry(&wait, current);
spin_lock_irqsave(&pool->lock, flags); spin_lock_irqsave(&pool->lock, flags);
if (pool->ptr == NULL) { /* not initialized */ if (pool->ptr == NULL) { /* not initialized */
snd_printd("seq: pool is not initialized\n"); snd_printd("seq: pool is not initialized\n");
...@@ -234,9 +236,12 @@ int snd_seq_cell_alloc(pool_t *pool, snd_seq_event_cell_t **cellp, int nonblock, ...@@ -234,9 +236,12 @@ int snd_seq_cell_alloc(pool_t *pool, snd_seq_event_cell_t **cellp, int nonblock,
} }
while (pool->free == NULL && ! nonblock && ! pool->closing) { while (pool->free == NULL && ! nonblock && ! pool->closing) {
spin_unlock(&pool->lock); set_current_state(TASK_INTERRUPTIBLE);
interruptible_sleep_on(&pool->output_sleep); add_wait_queue(&pool->output_sleep, &wait);
spin_lock(&pool->lock); spin_unlock_irq(&pool->lock);
schedule();
spin_lock_irq(&pool->lock);
remove_wait_queue(&pool->output_sleep, &wait);
/* interrupted? */ /* interrupted? */
if (signal_pending(current)) { if (signal_pending(current)) {
err = -ERESTARTSYS; err = -ERESTARTSYS;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment