docs/pwg/advanced-types.xml: Well done to Michael for catching my deliberate introduc...
authorJan Schmidt <thaytan@mad.scientist.com>
Wed, 24 Aug 2005 15:10:41 +0000 (15:10 +0000)
committerJan Schmidt <thaytan@mad.scientist.com>
Wed, 24 Aug 2005 15:10:41 +0000 (15:10 +0000)
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.

ChangeLog
docs/pwg/advanced-types.xml
gst/gstbin.c
gst/gstelement.h

index 8ad3afa..0e5e225 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
        * gst/gst.c (parse_debug_list): Accept e.g. GST_DEBUG=4 to mean
index 50ad26d..8e179f9 100644 (file)
@@ -346,7 +346,7 @@ plugin_init (GstPlugin *plugin)
            <entry>
               Note that some people think that this property is very ugly, 
              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.
            </entry>
           </row>
index 68b6db3..1c821cd 100644 (file)
@@ -582,11 +582,22 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
   gchar *elem_name;
   GstIterator *it;
 
-  /* grab element name so we can print it */
   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));
   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);
   /* the element must be in the bin's list of children */
   if (G_UNLIKELY (g_list_find (bin->children, element) == NULL))
@@ -615,11 +626,6 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
       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);
 
   /* 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);
 
   /* 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_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);
+
   /* element is really out of our control now */
   gst_object_unref (element);
 
@@ -650,6 +661,11 @@ not_in_bin:
     g_free (elem_name);
     return FALSE;
   }
+already_removing:
+  {
+    GST_UNLOCK (element);
+    return FALSE;
+  }
 }
 
 /**
index 1937456..bc08348 100644 (file)
@@ -93,10 +93,14 @@ typedef enum
 {
   /* ignore state changes from parent */
   GST_ELEMENT_LOCKED_STATE,
-
+  
   /* the element is a 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 */
   GST_ELEMENT_FLAG_LAST                = GST_OBJECT_FLAG_LAST + 16
 } GstElementFlags;