aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2004-05-10 19:48:33 -0400
committerDavid S. Miller <davem@nuts.davemloft.net>2004-05-10 19:48:33 -0400
commite026d85d9b6093cb79689d4410e7f2b36851a97d (patch)
tree663688e51087a889d5de0e55c564edb88b6cd2da /sound
parent3d29f7cb74c66bb60613f7c3d29a99d201995be3 (diff)
downloadhistory-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.c21
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