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
This commit is contained in:
Benjamin Otte 2003-05-06 21:58:49 +00:00
parent 1bdcd2e7b6
commit 05adc8c15c
2 changed files with 51 additions and 26 deletions

View file

@ -986,9 +986,7 @@ gst_element_add_ghost_pad (GstElement *element, GstPad *pad, const gchar *name)
void void
gst_element_remove_ghost_pad (GstElement *element, GstPad *pad) 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 (GST_IS_ELEMENT (element));
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_GHOST_PAD (pad)); g_return_if_fail (GST_IS_GHOST_PAD (pad));
/* FIXME this is redundant? /* 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 * from the element. gst_pad_remove_ghost_pad just removes the ghostpad from
* the real pad's ghost pad list * 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_element_remove_pad (element, pad);
gst_pad_remove_ghost_pad (GST_PAD (GST_PAD_REALIZE (pad)), pad);
gst_object_unref (GST_OBJECT (pad));
} }

View file

@ -46,9 +46,11 @@ GType _gst_pad_type = 0;
/***** Start with the base GstPad class *****/ /***** Start with the base GstPad class *****/
static void gst_pad_class_init (GstPadClass *klass); static void gst_pad_class_init (GstPadClass *klass);
static void gst_pad_init (GstPad *pad); 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, static gboolean gst_pad_try_relink_filtered_func (GstRealPad *srcpad, GstRealPad *sinkpad,
GstCaps *caps, gboolean clear); GstCaps *caps, gboolean clear);
static void gst_pad_set_pad_template (GstPad *pad, GstPadTemplate *templ);
#ifndef GST_DISABLE_LOADSAVE #ifndef GST_DISABLE_LOADSAVE
static xmlNodePtr gst_pad_save_thyself (GstObject *object, xmlNodePtr parent); static xmlNodePtr gst_pad_save_thyself (GstObject *object, xmlNodePtr parent);
@ -76,15 +78,28 @@ gst_pad_get_type (void)
static void static void
gst_pad_class_init (GstPadClass *klass) gst_pad_class_init (GstPadClass *klass)
{ {
GObjectClass *gobject_class;
gobject_class = (GObjectClass*) klass;
pad_parent_class = g_type_class_ref (GST_TYPE_OBJECT); pad_parent_class = g_type_class_ref (GST_TYPE_OBJECT);
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pad_dispose);
} }
static void static void
gst_pad_init (GstPad *pad) 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_class_init (GstRealPadClass *klass);
static void gst_real_pad_init (GstRealPad *pad); 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, static void gst_real_pad_set_property (GObject *object, guint prop_id,
const GValue *value, const GValue *value,
@ -116,8 +132,6 @@ static void gst_real_pad_get_property (GObject *object, guint prop_id,
GValue *value, GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
static void gst_real_pad_dispose (GObject *object);
GType _gst_real_pad_type = 0; GType _gst_real_pad_type = 0;
static GstPad *real_pad_parent_class = NULL; 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); g_return_val_if_fail (templ != NULL, NULL);
pad = gst_pad_new (name, templ->direction); pad = gst_pad_new (name, templ->direction);
gst_pad_set_pad_template (pad, templ);
gst_object_ref (GST_OBJECT (templ));
GST_PAD_PAD_TEMPLATE (pad) = templ;
g_signal_emit (G_OBJECT (templ), gst_pad_template_signals[TEMPL_PAD_CREATED], 0, pad);
return pad; return pad;
} }
@ -1130,6 +1140,16 @@ gst_pad_get_parent (GstPad *pad)
return GST_PAD_PARENT (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: * gst_pad_get_pad_template:
* @pad: a #GstPad to get the pad template of. * @pad: a #GstPad to get the pad template of.
@ -1239,14 +1259,13 @@ gst_pad_remove_ghost_pad (GstPad *pad,
{ {
GstRealPad *realpad; GstRealPad *realpad;
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad)); g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (ghostpad != NULL);
g_return_if_fail (GST_IS_GHOST_PAD (ghostpad)); g_return_if_fail (GST_IS_GHOST_PAD (ghostpad));
realpad = GST_PAD_REALIZE (pad); realpad = GST_PAD_REALIZE (pad);
g_return_if_fail (GST_GPAD_REALPAD (ghostpad) == realpad);
realpad->ghostpads = g_list_remove (realpad->ghostpads, ghostpad); 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)); 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 */ /* we destroy the ghostpads, because they are nothing without the real pad */
if (GST_REAL_PAD (pad)->ghostpads) { if (GST_REAL_PAD (pad)->ghostpads) {
GList *orig, *ghostpads; GList *orig, *ghostpads;
@ -2635,8 +2647,9 @@ gst_pad_get_element_private (GstPad *pad)
/***** ghost pads *****/ /***** ghost pads *****/
GType _gst_ghost_pad_type = 0; GType _gst_ghost_pad_type = 0;
static void gst_ghost_pad_class_init (GstGhostPadClass *klass); static void gst_ghost_pad_class_init (GstGhostPadClass *klass);
static void gst_ghost_pad_init (GstGhostPad *pad); static void gst_ghost_pad_init (GstGhostPad *pad);
static void gst_ghost_pad_dispose (GObject *object);
static GstPad *ghost_pad_parent_class = NULL; static GstPad *ghost_pad_parent_class = NULL;
/* static guint gst_ghost_pad_signals[LAST_SIGNAL] = { 0 }; */ /* static guint gst_ghost_pad_signals[LAST_SIGNAL] = { 0 }; */
@ -2667,12 +2680,24 @@ gst_ghost_pad_class_init (GstGhostPadClass *klass)
gobject_class = (GObjectClass*) klass; gobject_class = (GObjectClass*) klass;
ghost_pad_parent_class = g_type_class_ref (GST_TYPE_PAD); ghost_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_ghost_pad_dispose);
} }
static void static void
gst_ghost_pad_init (GstGhostPad *pad) 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); realpad = GST_PAD_REALIZE (realpad);
} }
GST_GPAD_REALPAD (ghostpad) = 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 */ /* add ourselves to the real pad's list of ghostpads */
gst_pad_add_ghost_pad (pad, GST_PAD (ghostpad)); gst_pad_add_ghost_pad (pad, GST_PAD (ghostpad));