diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2004-05-10 19:48:33 -0400 |
---|---|---|
committer | David S. Miller <davem@nuts.davemloft.net> | 2004-05-10 19:48:33 -0400 |
commit | e026d85d9b6093cb79689d4410e7f2b36851a97d (patch) | |
tree | 663688e51087a889d5de0e55c564edb88b6cd2da /sound | |
parent | 3d29f7cb74c66bb60613f7c3d29a99d201995be3 (diff) | |
download | history-e026d85d9b6093cb79689d4410e7f2b36851a97d.tar.gz |
[sound/oss i810] fix wait queue race in drain_dac
This particular one fixes a textbook race condition in drain_dac
that causes it to timeout when it shouldn't.
Diffstat (limited to 'sound')
-rw-r--r-- | sound/oss/i810_audio.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c index cb693b05c095f3..bc492c17389424 100644 --- a/sound/oss/i810_audio.c +++ b/sound/oss/i810_audio.c @@ -1241,6 +1241,17 @@ static int drain_dac(struct i810_state *state, int signals_allowed) spin_lock_irqsave(&state->card->lock, flags); i810_update_ptr(state); count = dmabuf->count; + + /* It seems that we have to set the current state to + * TASK_INTERRUPTIBLE every time to make the process + * really go to sleep. This also has to be *after* the + * update_ptr() call because update_ptr is likely to + * do a wake_up() which will unset this before we ever + * try to sleep, resuling in a tight loop in this code + * instead of actually sleeping and waiting for an + * interrupt to wake us up! + */ + __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&state->card->lock, flags); if (count <= 0) @@ -1260,16 +1271,6 @@ static int drain_dac(struct i810_state *state, int signals_allowed) break; } - /* It seems that we have to set the current state to - * TASK_INTERRUPTIBLE every time to make the process - * really go to sleep. This also has to be *after* the - * update_ptr() call because update_ptr is likely to - * do a wake_up() which will unset this before we ever - * try to sleep, resuling in a tight loop in this code - * instead of actually sleeping and waiting for an - * interrupt to wake us up! - */ - set_current_state(TASK_INTERRUPTIBLE); /* * set the timeout to significantly longer than it *should* * take for the DAC to drain the DMA buffer |