mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-02 08:42:32 +00:00
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
This commit is contained in:
parent
f99119cff6
commit
e25fd35125
3 changed files with 38 additions and 14 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2008-06-25 Thijs Vermeir <thijsvermeir@gmail.com>
|
||||||
|
|
||||||
|
* plugins/elements/gstmultiqueue.c:
|
||||||
|
* plugins/elements/gstmultiqueue.h:
|
||||||
|
Fix dead-lock in underrun_cb
|
||||||
|
|
||||||
2008-06-25 Wim Taymans <wim.taymans@collabora.co.uk>
|
2008-06-25 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||||
|
|
||||||
* docs/design/part-states.txt:
|
* docs/design/part-states.txt:
|
||||||
|
|
|
@ -1272,22 +1272,15 @@ compute_high_id (GstMultiQueue * mq)
|
||||||
#define IS_FILLED(format, value) ((sq->max_size.format) != 0 && \
|
#define IS_FILLED(format, value) ((sq->max_size.format) != 0 && \
|
||||||
(sq->max_size.format) <= (value))
|
(sq->max_size.format) <= (value))
|
||||||
|
|
||||||
/*
|
|
||||||
* GstSingleQueue functions
|
|
||||||
*/
|
|
||||||
static void
|
static void
|
||||||
single_queue_overrun_cb (GstDataQueue * dq, GstSingleQueue * sq)
|
single_queue_overrun_cb_unlocked (GstDataQueue * dq, GstSingleQueue * sq)
|
||||||
{
|
{
|
||||||
GstMultiQueue *mq = sq->mqueue;
|
GstMultiQueue *mq = sq->mqueue;
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
GstDataQueueSize size;
|
GstDataQueueSize size;
|
||||||
gboolean filled = TRUE;
|
|
||||||
|
|
||||||
gst_data_queue_get_level (sq->queue, &size);
|
gst_data_queue_get_level (sq->queue, &size);
|
||||||
|
mq->filled = FALSE;
|
||||||
GST_LOG_OBJECT (mq, "Single Queue %d is full", sq->id);
|
|
||||||
|
|
||||||
GST_MULTI_QUEUE_MUTEX_LOCK (mq);
|
|
||||||
|
|
||||||
/* if we have reached max visible we can maybe bump this
|
/* if we have reached max visible we can maybe bump this
|
||||||
* if another queue is empty, skip this if we can't grow anymore
|
* 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 */
|
/* 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);
|
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
|
||||||
|
|
||||||
if (filled) {
|
if (mq->filled) {
|
||||||
GST_DEBUG_OBJECT (mq, "A queue is filled, signalling overrun");
|
GST_DEBUG_OBJECT (mq, "A queue is filled, signalling overrun");
|
||||||
g_signal_emit (G_OBJECT (mq), gst_multi_queue_signals[SIGNAL_OVERRUN], 0);
|
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 */
|
/* prevent data starvation */
|
||||||
if (gst_data_queue_is_full (ssq->queue)) {
|
if (gst_data_queue_is_full (ssq->queue)) {
|
||||||
single_queue_overrun_cb (dq, ssq);
|
single_queue_overrun_cb_unlocked (dq, ssq);
|
||||||
all_empty = FALSE;
|
goto check_filled;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_data_queue_is_empty (ssq->queue)) {
|
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");
|
GST_DEBUG_OBJECT (mq, "All queues are empty, signalling it");
|
||||||
g_signal_emit (G_OBJECT (mq), gst_multi_queue_signals[SIGNAL_UNDERRUN], 0);
|
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
|
static gboolean
|
||||||
|
|
|
@ -68,6 +68,7 @@ struct _GstMultiQueue {
|
||||||
gint nextnotlinked; /* ID of the next queue not linked (-1 : none) */
|
gint nextnotlinked; /* ID of the next queue not linked (-1 : none) */
|
||||||
|
|
||||||
gint numwaiting; /* number of not-linked pads waiting */
|
gint numwaiting; /* number of not-linked pads waiting */
|
||||||
|
gboolean filled; /* overrun detected */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstMultiQueueClass {
|
struct _GstMultiQueueClass {
|
||||||
|
|
Loading…
Reference in a new issue