From 05adc8c15c41121ed7f156f7a7604496d97fd3fe Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 6 May 2003 21:58:49 +0000 Subject: [PATCH] implement proper refcounting of pad's templates and references from real pads to their ghost pads and the other way a... Original commit message from CVS: implement proper refcounting of pad's templates and references from real pads to their ghost pads and the other way around - this fixes the segfaults in the player --- gst/gstelement.c | 6 ++-- gst/gstpad.c | 71 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/gst/gstelement.c b/gst/gstelement.c index 0320fa64bf..d5aefe9cd9 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -986,9 +986,7 @@ gst_element_add_ghost_pad (GstElement *element, GstPad *pad, const gchar *name) void gst_element_remove_ghost_pad (GstElement *element, GstPad *pad) { - g_return_if_fail (element != NULL); g_return_if_fail (GST_IS_ELEMENT (element)); - g_return_if_fail (pad != NULL); g_return_if_fail (GST_IS_GHOST_PAD (pad)); /* FIXME this is redundant? @@ -996,8 +994,10 @@ gst_element_remove_ghost_pad (GstElement *element, GstPad *pad) * from the element. gst_pad_remove_ghost_pad just removes the ghostpad from * the real pad's ghost pad list */ - gst_pad_remove_ghost_pad (GST_PAD (GST_PAD_REALIZE (pad)), pad); + gst_object_ref (GST_OBJECT (pad)); gst_element_remove_pad (element, pad); + gst_pad_remove_ghost_pad (GST_PAD (GST_PAD_REALIZE (pad)), pad); + gst_object_unref (GST_OBJECT (pad)); } diff --git a/gst/gstpad.c b/gst/gstpad.c index a16e741e10..42fce5348f 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -46,9 +46,11 @@ GType _gst_pad_type = 0; /***** Start with the base GstPad class *****/ static void gst_pad_class_init (GstPadClass *klass); static void gst_pad_init (GstPad *pad); +static void gst_pad_dispose (GObject *object); static gboolean gst_pad_try_relink_filtered_func (GstRealPad *srcpad, GstRealPad *sinkpad, GstCaps *caps, gboolean clear); +static void gst_pad_set_pad_template (GstPad *pad, GstPadTemplate *templ); #ifndef GST_DISABLE_LOADSAVE static xmlNodePtr gst_pad_save_thyself (GstObject *object, xmlNodePtr parent); @@ -76,15 +78,28 @@ gst_pad_get_type (void) static void gst_pad_class_init (GstPadClass *klass) { + GObjectClass *gobject_class; + + gobject_class = (GObjectClass*) klass; + pad_parent_class = g_type_class_ref (GST_TYPE_OBJECT); + + gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pad_dispose); } static void gst_pad_init (GstPad *pad) { - pad->element_private = NULL; + /* all structs are initialized to NULL by glib */ +} +static void +gst_pad_dispose (GObject *object) +{ + GstPad *pad = GST_PAD (object); - pad->padtemplate = NULL; + gst_pad_set_pad_template (pad, NULL); + + G_OBJECT_CLASS (pad_parent_class)->dispose (object); } @@ -108,6 +123,7 @@ enum { static void gst_real_pad_class_init (GstRealPadClass *klass); static void gst_real_pad_init (GstRealPad *pad); +static void gst_real_pad_dispose (GObject *object); static void gst_real_pad_set_property (GObject *object, guint prop_id, const GValue *value, @@ -116,8 +132,6 @@ static void gst_real_pad_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -static void gst_real_pad_dispose (GObject *object); - GType _gst_real_pad_type = 0; static GstPad *real_pad_parent_class = NULL; @@ -322,12 +336,8 @@ gst_pad_custom_new_from_template (GType type, GstPadTemplate *templ, g_return_val_if_fail (templ != NULL, NULL); pad = gst_pad_new (name, templ->direction); - - gst_object_ref (GST_OBJECT (templ)); - GST_PAD_PAD_TEMPLATE (pad) = templ; + gst_pad_set_pad_template (pad, templ); - g_signal_emit (G_OBJECT (templ), gst_pad_template_signals[TEMPL_PAD_CREATED], 0, pad); - return pad; } @@ -1130,6 +1140,16 @@ gst_pad_get_parent (GstPad *pad) return GST_PAD_PARENT (pad); } +static void +gst_pad_set_pad_template (GstPad *pad, GstPadTemplate *templ) +{ + /* this function would need checks if it weren't static */ + + gst_object_replace ((GstObject **) &pad->padtemplate, (GstObject *) templ); + + if (templ) + g_signal_emit (G_OBJECT (templ), gst_pad_template_signals[TEMPL_PAD_CREATED], 0, pad); +} /** * gst_pad_get_pad_template: * @pad: a #GstPad to get the pad template of. @@ -1239,14 +1259,13 @@ gst_pad_remove_ghost_pad (GstPad *pad, { GstRealPad *realpad; - g_return_if_fail (pad != NULL); g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (ghostpad != NULL); g_return_if_fail (GST_IS_GHOST_PAD (ghostpad)); - realpad = GST_PAD_REALIZE (pad); + g_return_if_fail (GST_GPAD_REALPAD (ghostpad) == realpad); realpad->ghostpads = g_list_remove (realpad->ghostpads, ghostpad); + GST_GPAD_REALPAD (ghostpad) = NULL; } /** @@ -2081,13 +2100,6 @@ gst_real_pad_dispose (GObject *object) GST_DEBUG (GST_CAT_REFCOUNTING, "dispose %s:%s", GST_DEBUG_PAD_NAME(pad)); - if (GST_PAD_PAD_TEMPLATE (pad)){ - GST_DEBUG (GST_CAT_REFCOUNTING, "unreffing padtemplate'%s'", - GST_OBJECT_NAME (GST_PAD_PAD_TEMPLATE (pad))); - gst_object_unref (GST_OBJECT (GST_PAD_PAD_TEMPLATE (pad))); - GST_PAD_PAD_TEMPLATE (pad) = NULL; - } - /* we destroy the ghostpads, because they are nothing without the real pad */ if (GST_REAL_PAD (pad)->ghostpads) { GList *orig, *ghostpads; @@ -2635,8 +2647,9 @@ gst_pad_get_element_private (GstPad *pad) /***** ghost pads *****/ GType _gst_ghost_pad_type = 0; -static void gst_ghost_pad_class_init (GstGhostPadClass *klass); -static void gst_ghost_pad_init (GstGhostPad *pad); +static void gst_ghost_pad_class_init (GstGhostPadClass *klass); +static void gst_ghost_pad_init (GstGhostPad *pad); +static void gst_ghost_pad_dispose (GObject *object); static GstPad *ghost_pad_parent_class = NULL; /* static guint gst_ghost_pad_signals[LAST_SIGNAL] = { 0 }; */ @@ -2667,12 +2680,24 @@ gst_ghost_pad_class_init (GstGhostPadClass *klass) gobject_class = (GObjectClass*) klass; ghost_pad_parent_class = g_type_class_ref (GST_TYPE_PAD); + + gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_ghost_pad_dispose); } static void gst_ghost_pad_init (GstGhostPad *pad) { - pad->realpad = NULL; + /* zeroed by glib */ +} +static void +gst_ghost_pad_dispose (GObject *object) +{ + GstGhostPad *pad = GST_GHOST_PAD (object); + + if (pad->realpad) + gst_pad_remove_ghost_pad((GstPad *) pad->realpad, (GstPad *) pad); + + G_OBJECT_CLASS (ghost_pad_parent_class)->dispose (object); } /** @@ -2705,7 +2730,7 @@ gst_ghost_pad_new (const gchar *name, realpad = GST_PAD_REALIZE (realpad); } GST_GPAD_REALPAD (ghostpad) = realpad; - GST_PAD_PAD_TEMPLATE (ghostpad) = GST_PAD_PAD_TEMPLATE (pad); + gst_pad_set_pad_template (GST_PAD (ghostpad), GST_PAD_PAD_TEMPLATE (pad)); /* add ourselves to the real pad's list of ghostpads */ gst_pad_add_ghost_pad (pad, GST_PAD (ghostpad));