docs/pwg/advanced-types.xml: Well done to Michael for catching my deliberate introduction of this spelling mistake.

Original commit message from CVS:
* docs/pwg/advanced-types.xml:
Well done to Michael for catching my deliberate introduction
of this spelling mistake.
* gst/gstbin.c: (gst_bin_remove_func), (bin_bus_handler):
* gst/gstelement.h:
Add GST_ELEMENT_UNPARENTING to prevent races so that we can
unlink pads before removing the element from the bin.
This commit is contained in:
Jan Schmidt 2005-08-24 15:10:41 +00:00
parent 76fffe8fc5
commit 8aa248c92b
4 changed files with 39 additions and 9 deletions

View file

@ -1,3 +1,13 @@
2005-08-24 Jan Schmidt <thaytan@mad.scientist.com>
* docs/pwg/advanced-types.xml:
Well done to Michael for catching my deliberate introduction
of this spelling mistake.
* gst/gstbin.c: (gst_bin_remove_func), (bin_bus_handler):
* gst/gstelement.h:
Add GST_ELEMENT_UNPARENTING to prevent races so that we can
unlink pads before removing the element from the bin.
2005-08-24 Andy Wingo <wingo@pobox.com> 2005-08-24 Andy Wingo <wingo@pobox.com>
* gst/gst.c (parse_debug_list): Accept e.g. GST_DEBUG=4 to mean * gst/gst.c (parse_debug_list): Accept e.g. GST_DEBUG=4 to mean

View file

@ -346,7 +346,7 @@ plugin_init (GstPlugin *plugin)
<entry> <entry>
Note that some people think that this property is very ugly, Note that some people think that this property is very ugly,
whereas others think it is vital for the use of &GStreamer; in whereas others think it is vital for the use of &GStreamer; in
proffessional audio applications. The special value zero is professional audio applications. The special value zero is
reserved and implies that size is variable between buffers. reserved and implies that size is variable between buffers.
</entry> </entry>
</row> </row>

View file

@ -582,11 +582,22 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
gchar *elem_name; gchar *elem_name;
GstIterator *it; GstIterator *it;
/* grab element name so we can print it */
GST_LOCK (element); GST_LOCK (element);
/* Check if the element is already being removed and immediately
* return */
if (G_UNLIKELY (GST_FLAG_IS_SET (element, GST_ELEMENT_UNPARENTING)))
goto already_removing;
GST_FLAG_SET (element, GST_ELEMENT_UNPARENTING);
/* grab element name so we can print it */
elem_name = g_strdup (GST_ELEMENT_NAME (element)); elem_name = g_strdup (GST_ELEMENT_NAME (element));
GST_UNLOCK (element); GST_UNLOCK (element);
/* unlink all linked pads */
it = gst_element_iterate_pads (element);
gst_iterator_foreach (it, (GFunc) unlink_pads, element);
gst_iterator_free (it);
GST_LOCK (bin); GST_LOCK (bin);
/* the element must be in the bin's list of children */ /* the element must be in the bin's list of children */
if (G_UNLIKELY (g_list_find (bin->children, element) == NULL)) if (G_UNLIKELY (g_list_find (bin->children, element) == NULL))
@ -615,11 +626,6 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
elem_name); elem_name);
g_free (elem_name); g_free (elem_name);
/* unlink all linked pads */
it = gst_element_iterate_pads (element);
gst_iterator_foreach (it, (GFunc) unlink_pads, element);
gst_iterator_free (it);
gst_element_set_bus (element, NULL); gst_element_set_bus (element, NULL);
/* unlock any waiters for the state change. It is possible that /* unlock any waiters for the state change. It is possible that
@ -631,11 +637,16 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
GST_STATE_UNLOCK (element); GST_STATE_UNLOCK (element);
/* we ref here because after the _unparent() the element can be disposed /* we ref here because after the _unparent() the element can be disposed
* and we still need it to fire a signal. */ * and we still need it to reset the UNPARENTING flag and fire a signal. */
gst_object_ref (element); gst_object_ref (element);
gst_object_unparent (GST_OBJECT_CAST (element)); gst_object_unparent (GST_OBJECT_CAST (element));
GST_LOCK (element);
GST_FLAG_UNSET (element, GST_ELEMENT_UNPARENTING);
GST_UNLOCK (element);
g_signal_emit (G_OBJECT (bin), gst_bin_signals[ELEMENT_REMOVED], 0, element); g_signal_emit (G_OBJECT (bin), gst_bin_signals[ELEMENT_REMOVED], 0, element);
/* element is really out of our control now */ /* element is really out of our control now */
gst_object_unref (element); gst_object_unref (element);
@ -650,6 +661,11 @@ not_in_bin:
g_free (elem_name); g_free (elem_name);
return FALSE; return FALSE;
} }
already_removing:
{
GST_UNLOCK (element);
return FALSE;
}
} }
/** /**

View file

@ -93,10 +93,14 @@ typedef enum
{ {
/* ignore state changes from parent */ /* ignore state changes from parent */
GST_ELEMENT_LOCKED_STATE, GST_ELEMENT_LOCKED_STATE,
/* the element is a sink */ /* the element is a sink */
GST_ELEMENT_IS_SINK, GST_ELEMENT_IS_SINK,
/* Child is being removed from the parent bin. gst_bin_remove on a
* child already being removed immediately returns FALSE */
GST_ELEMENT_UNPARENTING,
/* use some padding for future expansion */ /* use some padding for future expansion */
GST_ELEMENT_FLAG_LAST = GST_OBJECT_FLAG_LAST + 16 GST_ELEMENT_FLAG_LAST = GST_OBJECT_FLAG_LAST + 16
} GstElementFlags; } GstElementFlags;