From: Thijs Vermeir Date: Wed, 25 Jun 2008 15:39:02 +0000 (+0000) Subject: plugins/elements/gstmultiqueue.*: Fix dead-lock in underrun_cb X-Git-Tag: RELEASE-0_10_21~123 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e25fd3512570d505a3a9031d8adea6e5370fa5f5;p=platform%2Fupstream%2Fgstreamer.git plugins/elements/gstmultiqueue.*: Fix dead-lock in underrun_cb Original commit message from CVS: * plugins/elements/gstmultiqueue.c: * plugins/elements/gstmultiqueue.h: Fix dead-lock in underrun_cb --- diff --git a/ChangeLog b/ChangeLog index a0e88fb..caf8bb1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-06-25 Thijs Vermeir + + * plugins/elements/gstmultiqueue.c: + * plugins/elements/gstmultiqueue.h: + Fix dead-lock in underrun_cb + 2008-06-25 Wim Taymans * docs/design/part-states.txt: diff --git a/plugins/elements/gstmultiqueue.c b/plugins/elements/gstmultiqueue.c index abe8c18..1e0b9ba 100644 --- a/plugins/elements/gstmultiqueue.c +++ b/plugins/elements/gstmultiqueue.c @@ -1272,22 +1272,15 @@ compute_high_id (GstMultiQueue * mq) #define IS_FILLED(format, value) ((sq->max_size.format) != 0 && \ (sq->max_size.format) <= (value)) -/* - * GstSingleQueue functions - */ static void -single_queue_overrun_cb (GstDataQueue * dq, GstSingleQueue * sq) +single_queue_overrun_cb_unlocked (GstDataQueue * dq, GstSingleQueue * sq) { GstMultiQueue *mq = sq->mqueue; GList *tmp; GstDataQueueSize size; - gboolean filled = TRUE; gst_data_queue_get_level (sq->queue, &size); - - GST_LOG_OBJECT (mq, "Single Queue %d is full", sq->id); - - GST_MULTI_QUEUE_MUTEX_LOCK (mq); + mq->filled = FALSE; /* if we have reached max visible we can maybe bump this * if another queue is empty, skip this if we can't grow anymore @@ -1309,13 +1302,30 @@ single_queue_overrun_cb (GstDataQueue * dq, GstSingleQueue * sq) } } /* check if the queue is still full */ - filled = gst_data_queue_is_full (sq->queue); + mq->filled = gst_data_queue_is_full (sq->queue); } +} + +/* + * GstSingleQueue functions + */ +static void +single_queue_overrun_cb (GstDataQueue * dq, GstSingleQueue * sq) +{ + GstMultiQueue *mq = sq->mqueue; + + GST_LOG_OBJECT (mq, "Single Queue %d is full", sq->id); + + GST_MULTI_QUEUE_MUTEX_LOCK (mq); + + single_queue_overrun_cb_unlocked (dq, sq); + GST_MULTI_QUEUE_MUTEX_UNLOCK (mq); - if (filled) { + if (mq->filled) { GST_DEBUG_OBJECT (mq, "A queue is filled, signalling overrun"); g_signal_emit (G_OBJECT (mq), gst_multi_queue_signals[SIGNAL_OVERRUN], 0); + mq->filled = FALSE; } } @@ -1338,9 +1348,8 @@ single_queue_underrun_cb (GstDataQueue * dq, GstSingleQueue * sq) /* prevent data starvation */ if (gst_data_queue_is_full (ssq->queue)) { - single_queue_overrun_cb (dq, ssq); - all_empty = FALSE; - break; + single_queue_overrun_cb_unlocked (dq, ssq); + goto check_filled; } if (!gst_data_queue_is_empty (ssq->queue)) { @@ -1354,6 +1363,14 @@ single_queue_underrun_cb (GstDataQueue * dq, GstSingleQueue * sq) GST_DEBUG_OBJECT (mq, "All queues are empty, signalling it"); g_signal_emit (G_OBJECT (mq), gst_multi_queue_signals[SIGNAL_UNDERRUN], 0); } + return; + +check_filled: + if (mq->filled) { + GST_DEBUG_OBJECT (mq, "A queue is filled, signalling overrun"); + g_signal_emit (G_OBJECT (mq), gst_multi_queue_signals[SIGNAL_OVERRUN], 0); + mq->filled = FALSE; + } } static gboolean diff --git a/plugins/elements/gstmultiqueue.h b/plugins/elements/gstmultiqueue.h index 4874563..1666b5d 100644 --- a/plugins/elements/gstmultiqueue.h +++ b/plugins/elements/gstmultiqueue.h @@ -68,6 +68,7 @@ struct _GstMultiQueue { gint nextnotlinked; /* ID of the next queue not linked (-1 : none) */ gint numwaiting; /* number of not-linked pads waiting */ + gboolean filled; /* overrun detected */ }; struct _GstMultiQueueClass {