mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 22:36:33 +00:00
bin: avoid false 'loop detected' warnings
When we detect a pad unlink in progress, we will not be updating the degree of the parent element. This can cause false loop detected warnings because the degree counter is invalid. Handle this case by marking the iterator as 'dirty' when we detect a pad unlink and avoid emiting the warning in this case. We have to continue our state change as good as we can, we will eventually resync when the pad unlink completed.
This commit is contained in:
parent
bcb9eab392
commit
1ab11faf48
1 changed files with 12 additions and 1 deletions
13
gst/gstbin.c
13
gst/gstbin.c
|
@ -1717,6 +1717,7 @@ typedef struct _GstBinSortIterator
|
|||
GstElement *best; /* next element with least dependencies */
|
||||
gint best_deg; /* best degree */
|
||||
GHashTable *hash; /* hashtable with element dependencies */
|
||||
gboolean dirty; /* we detected structure change */
|
||||
} GstBinSortIterator;
|
||||
|
||||
/* we add and subtract 1 to make sure we don't confuse NULL and 0 */
|
||||
|
@ -1820,6 +1821,13 @@ update_degree (GstElement * element, GstBinSortIterator * bit)
|
|||
* srcpad, check if it's busy in a link/unlink */
|
||||
if (G_UNLIKELY (find_message (bit->bin, GST_OBJECT_CAST (peer),
|
||||
GST_MESSAGE_STRUCTURE_CHANGE))) {
|
||||
/* mark the iterator as dirty because we won't be updating the degree
|
||||
* of the peer parent now. This would result in the 'loop detected'
|
||||
* later on because the peer parent element could become the best next
|
||||
* element with a degree > 0. We will simply continue our state
|
||||
* changes and we'll eventually resync when the unlink completed and
|
||||
* the iterator cookie is updated. */
|
||||
bit->dirty = TRUE;
|
||||
gst_object_unref (peer);
|
||||
continue;
|
||||
}
|
||||
|
@ -1905,7 +1913,9 @@ gst_bin_sort_iterator_next (GstBinSortIterator * bit, gpointer * result)
|
|||
bit->best_deg = G_MAXINT;
|
||||
g_list_foreach (bin->children, (GFunc) find_element, bit);
|
||||
if ((best = bit->best)) {
|
||||
if (bit->best_deg != 0) {
|
||||
/* when we detected an unlink, don't warn because our degrees might be
|
||||
* screwed up. We will resync later */
|
||||
if (bit->best_deg != 0 && !bit->dirty) {
|
||||
/* we don't fail on this one yet */
|
||||
GST_WARNING_OBJECT (bin, "loop dected in graph");
|
||||
g_warning ("loop detected in the graph of bin %s!!",
|
||||
|
@ -1941,6 +1951,7 @@ gst_bin_sort_iterator_resync (GstBinSortIterator * bit)
|
|||
GstBin *bin = bit->bin;
|
||||
|
||||
GST_DEBUG_OBJECT (bin, "resync");
|
||||
bit->dirty = FALSE;
|
||||
clear_queue (bit->queue);
|
||||
/* reset degrees */
|
||||
g_list_foreach (bin->children, (GFunc) reset_degree, bit);
|
||||
|
|
Loading…
Reference in a new issue