Skip to content

Commit

Permalink
[ALSA] Fix possible races in timer callbacks
Browse files Browse the repository at this point in the history
Fix possible races in timer callbacks.

Signed-off-by: Takashi Iwai <[email protected]>
  • Loading branch information
tiwai authored and Jaroslav Kysela committed Jan 3, 2006
1 parent 2eb061f commit b32425a
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 15 deletions.
5 changes: 3 additions & 2 deletions sound/core/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -662,12 +662,13 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
struct snd_timer_instance *ti, *ts;
unsigned long resolution, ticks;
struct list_head *p, *q, *n, *ack_list_head;
unsigned long flags;
int use_tasklet = 0;

if (timer == NULL)
return;

spin_lock(&timer->lock);
spin_lock_irqsave(&timer->lock, flags);

/* remember the current resolution */
if (timer->hw.c_resolution)
Expand Down Expand Up @@ -752,7 +753,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)

/* do we have any slow callbacks? */
use_tasklet = !list_empty(&timer->sack_list_head);
spin_unlock(&timer->lock);
spin_unlock_irqrestore(&timer->lock, flags);

if (use_tasklet)
tasklet_hi_schedule(&timer->task_queue);
Expand Down
10 changes: 5 additions & 5 deletions sound/drivers/dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,20 +231,20 @@ static int snd_card_dummy_pcm_prepare(struct snd_pcm_substream *substream)
static void snd_card_dummy_pcm_timer_function(unsigned long data)
{
struct snd_dummy_pcm *dpcm = (struct snd_dummy_pcm *)data;
unsigned long flags;

spin_lock(&dpcm->lock);
spin_lock_irqsave(&dpcm->lock, flags);
dpcm->timer.expires = 1 + jiffies;
add_timer(&dpcm->timer);
dpcm->pcm_irq_pos += dpcm->pcm_jiffie;
dpcm->pcm_buf_pos += dpcm->pcm_jiffie;
dpcm->pcm_buf_pos %= dpcm->pcm_size;
if (dpcm->pcm_irq_pos >= dpcm->pcm_count) {
dpcm->pcm_irq_pos %= dpcm->pcm_count;
spin_unlock(&dpcm->lock);
spin_unlock_irqrestore(&dpcm->lock, flags);
snd_pcm_period_elapsed(dpcm->substream);
spin_lock(&dpcm->lock);
}
spin_unlock(&dpcm->lock);
} else
spin_unlock_irqrestore(&dpcm->lock, flags);
}

static snd_pcm_uframes_t snd_card_dummy_pcm_pointer(struct snd_pcm_substream *substream)
Expand Down
5 changes: 3 additions & 2 deletions sound/drivers/mpu401/mpu401_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,13 @@ irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *reg
static void snd_mpu401_uart_timer(unsigned long data)
{
struct snd_mpu401 *mpu = (struct snd_mpu401 *)data;
unsigned long flags;

spin_lock(&mpu->timer_lock);
spin_lock_irqsave(&mpu->timer_lock, flags);
/*mpu->mode |= MPU401_MODE_TIMER;*/
mpu->timer.expires = 1 + jiffies;
add_timer(&mpu->timer);
spin_unlock(&mpu->timer_lock);
spin_unlock_irqrestore(&mpu->timer_lock, flags);
if (mpu->rmidi)
_snd_mpu401_uart_interrupt(mpu);
}
Expand Down
5 changes: 3 additions & 2 deletions sound/drivers/opl3/opl3_midi.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,11 @@ void snd_opl3_timer_func(unsigned long data)
{

struct snd_opl3 *opl3 = (struct snd_opl3 *)data;
unsigned long flags;
int again = 0;
int i;

spin_lock(&opl3->sys_timer_lock);
spin_lock_irqsave(&opl3->sys_timer_lock, flags);
for (i = 0; i < opl3->max_voices; i++) {
struct snd_opl3_voice *vp = &opl3->voices[i];
if (vp->state > 0 && vp->note_off_check) {
Expand All @@ -257,7 +258,7 @@ void snd_opl3_timer_func(unsigned long data)
} else {
opl3->sys_timer_status = 0;
}
spin_unlock(&opl3->sys_timer_lock);
spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
}

/*
Expand Down
5 changes: 3 additions & 2 deletions sound/pci/korg1212/korg1212.c
Original file line number Diff line number Diff line change
Expand Up @@ -609,8 +609,9 @@ static void snd_korg1212_SendStopAndWait(struct snd_korg1212 *korg1212)
static void snd_korg1212_timer_func(unsigned long data)
{
struct snd_korg1212 *korg1212 = (struct snd_korg1212 *) data;
unsigned long flags;

spin_lock(&korg1212->lock);
spin_lock_irqsave(&korg1212->lock, flags);
if (korg1212->sharedBufferPtr->cardCommand == 0) {
/* ack'ed */
korg1212->stop_pending_cnt = 0;
Expand All @@ -632,7 +633,7 @@ static void snd_korg1212_timer_func(unsigned long data)
stateName[korg1212->cardState]);
}
}
spin_unlock(&korg1212->lock);
spin_unlock_irqrestore(&korg1212->lock, flags);
}

static int snd_korg1212_TurnOnIdleMonitor(struct snd_korg1212 *korg1212)
Expand Down
5 changes: 3 additions & 2 deletions sound/synth/emux/emux_synth.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,10 @@ void snd_emux_timer_callback(unsigned long data)
{
struct snd_emux *emu = (struct snd_emux *) data;
struct snd_emux_voice *vp;
unsigned long flags;
int ch, do_again = 0;

spin_lock(&emu->voice_lock);
spin_lock_irqsave(&emu->voice_lock, flags);
for (ch = 0; ch < emu->max_voices; ch++) {
vp = &emu->voices[ch];
if (vp->state == SNDRV_EMUX_ST_PENDING) {
Expand All @@ -225,7 +226,7 @@ void snd_emux_timer_callback(unsigned long data)
emu->timer_active = 1;
} else
emu->timer_active = 0;
spin_unlock(&emu->voice_lock);
spin_unlock_irqrestore(&emu->voice_lock, flags);
}

/*
Expand Down

0 comments on commit b32425a

Please sign in to comment.