rendered paste body# HG changeset patch
# User Matthias Kretz <kretz@kde.org>
# Date 1196696873 -3600
# Node ID cda2260aa2199e294282c1c3cfd7082a7ee6dc73
# Parent 736094cc72eb7a32005302d06f27c7fb0e7be33b
In ao_loop only read the first buffer and remove it from the fifo only when the buffer has been written or is about to be discarded. This fixes the race between ao_loop and ao_close for good. Now fifo_remove_int may signal empty again right after removing the last buffer from the fifo.
diff -r 736094cc72eb -r cda2260aa219 src/xine-engine/audio_out.c
--- a/src/xine-engine/audio_out.c Sun Dec 02 23:43:03 2007 +0100
+++ b/src/xine-engine/audio_out.c Mon Dec 03 16:47:53 2007 +0100
@@ -338,9 +338,7 @@ static void fifo_append (audio_fifo_t *f
pthread_mutex_unlock (&fifo->mutex);
}
-static audio_buffer_t *fifo_remove_int (audio_fifo_t *fifo, int blocking) {
- audio_buffer_t *buf;
-
+static audio_buffer_t *fifo_peek_int (audio_fifo_t *fifo, int blocking) {
while (!fifo->first) {
pthread_cond_signal (&fifo->empty);
if (blocking)
@@ -355,8 +353,11 @@ static audio_buffer_t *fifo_remove_int (
return NULL;
}
}
-
- buf = fifo->first;
+ return fifo->first;
+}
+
+static audio_buffer_t *fifo_remove_int (audio_fifo_t *fifo, int blocking) {
+ audio_buffer_t *buf = fifo_peek_int(fifo, blocking);
fifo->first = buf->next;
@@ -364,11 +365,23 @@ static audio_buffer_t *fifo_remove_int (
fifo->last = NULL;
fifo->num_buffers = 0;
+ pthread_cond_signal (&fifo->empty);
} else
fifo->num_buffers--;
buf->next = NULL;
+
+ return buf;
+}
+
+static audio_buffer_t *fifo_peek (audio_fifo_t *fifo) {
+
+ audio_buffer_t *buf;
+
+ pthread_mutex_lock (&fifo->mutex);
+ buf = fifo_peek_int(fifo, 1);
+ pthread_mutex_unlock (&fifo->mutex);
return buf;
}
@@ -994,7 +1007,7 @@ static void *ao_loop (void *this_gen) {
if (!in_buf) {
lprintf ("loop: get buf from fifo\n");
- in_buf = fifo_remove (this->out_fifo);
+ in_buf = fifo_peek (this->out_fifo);
bufs_since_sync++;
lprintf ("got a buffer\n");
}
@@ -1007,6 +1020,7 @@ static void *ao_loop (void *this_gen) {
}
if (this->discard_buffers) {
+ fifo_remove (this->out_fifo);
if (in_buf->stream)
_x_refcounter_dec(in_buf->stream->refcounter);
fifo_append (this->free_fifo, in_buf);
@@ -1033,6 +1047,7 @@ static void *ao_loop (void *this_gen) {
cur_time = this->clock->get_current_time (this->clock);
if (in_buf->vpts < cur_time ) {
lprintf ("loop: next fifo\n");
+ fifo_remove (this->out_fifo);
if (in_buf->stream)
_x_refcounter_dec(in_buf->stream->refcounter);
fifo_append (this->free_fifo, in_buf);
@@ -1157,6 +1172,7 @@ static void *ao_loop (void *this_gen) {
/* drop package */
lprintf ("loop: drop package, next fifo\n");
+ fifo_remove (this->out_fifo);
if (in_buf->stream)
_x_refcounter_dec(in_buf->stream->refcounter);
fifo_append (this->free_fifo, in_buf);
@@ -1223,6 +1239,7 @@ static void *ao_loop (void *this_gen) {
} else {
result = 0;
}
+ fifo_remove (this->out_fifo);
if( result < 0 ) {
/* device unplugged. */