From 3945b0600ba44b29e1fac17f662948ae13aca55f Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 3 Feb 2004 22:13:13 +0000 Subject: [PATCH] gst/gststructure.c: fix huge memleak Original commit message from CVS: 2004-02-03 Benjamin Otte * gst/gststructure.c: (gst_structure_from_string): fix huge memleak * gst/elements/gsttypefind.c: (gst_type_find_element_have_type), (new_entry), (gst_type_find_element_chain): * gst/gstelement.c: (gst_element_base_class_init), (gst_element_class_set_details): * gst/gstpad.c: (gst_pad_can_link_filtered): fix smaller memleaks * gst/gstpad.c: (gst_real_pad_dispose): check that explicit caps are gone * gst/gststructure.c: (gst_structure_free): actually free the structure * gst/gstelement.c: (gst_element_clear_pad_caps): unset explicit caps --- ChangeLog | 17 +++++++++++++++++ common | 2 +- gst/elements/gsttypefind.c | 13 +++++++++---- gst/gstelement.c | 6 ++++-- gst/gstpad.c | 10 +++++++++- gst/gststructure.c | 31 ++++++++++++++++--------------- plugins/elements/gsttypefind.c | 13 +++++++++---- 7 files changed, 65 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 241537b..8c5b284 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2004-02-03 Benjamin Otte + + * gst/gststructure.c: (gst_structure_from_string): + fix huge memleak + * gst/elements/gsttypefind.c: (gst_type_find_element_have_type), + (new_entry), (gst_type_find_element_chain): + * gst/gstelement.c: (gst_element_base_class_init), + (gst_element_class_set_details): + * gst/gstpad.c: (gst_pad_can_link_filtered): + fix smaller memleaks + * gst/gstpad.c: (gst_real_pad_dispose): + check that explicit caps are gone + * gst/gststructure.c: (gst_structure_free): + actually free the structure + * gst/gstelement.c: (gst_element_clear_pad_caps): + unset explicit caps + 2004-02-03 Thomas Vander Stichele * tools/Makefile.am: diff --git a/common b/common index 0f9fe90..28760b0 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 0f9fe900b0757fd2450454a1af24146b47aaaac2 +Subproject commit 28760b093e73a78cdd0c1fba76baa5d87dc2c0f2 diff --git a/gst/elements/gsttypefind.c b/gst/elements/gsttypefind.c index 384b9bd..1ffdfbc 100644 --- a/gst/elements/gsttypefind.c +++ b/gst/elements/gsttypefind.c @@ -124,7 +124,7 @@ gst_type_find_element_have_type (GstTypeFindElement *typefind, guint probability GST_INFO_OBJECT (typefind, "found caps %" GST_PTR_FORMAT, caps); typefind->caps = gst_caps_copy (caps); - gst_pad_set_explicit_caps (typefind->src, gst_caps_copy(caps)); + gst_pad_set_explicit_caps (typefind->src, caps); } static void gst_type_find_element_base_init (gpointer g_class) @@ -282,6 +282,12 @@ typedef struct { GList * buffers; GstTypeFindElement * self; } TypeFindEntry; + +static inline TypeFindEntry * +new_entry (void) +{ + return g_new0 (TypeFindEntry, 1); +} static void free_entry_buffers (TypeFindEntry *entry) { @@ -499,7 +505,7 @@ gst_type_find_element_chain (GstPad *pad, GstData *data) all_factories = g_list_sort (all_factories, compare_type_find_factory); walk = all_factories; while (all_factories) { - entry = g_new0 (TypeFindEntry, 1); + entry = new_entry (); entry->factory = GST_TYPE_FIND_FACTORY (all_factories->data); entry->self = typefind; @@ -530,7 +536,6 @@ gst_type_find_element_chain (GstPad *pad, GstData *data) GstCaps *found_caps = entry->caps; guint probability = entry->probability; - found_caps = gst_caps_copy (found_caps); GST_INFO_OBJECT (typefind, "'%s' returned %u/%u probability, using it NOW", GST_PLUGIN_FEATURE_NAME (entry->factory), probability, typefind->max_probability); while (walk) { @@ -545,7 +550,7 @@ gst_type_find_element_chain (GstPad *pad, GstData *data) typefind->possibilities = NULL; g_list_free (typefind->possibilities); g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0, probability, found_caps); - gst_caps_free (found_caps); + free_entry (entry); } else { typefind->possibilities = g_list_prepend (typefind->possibilities, entry); } diff --git a/gst/gstelement.c b/gst/gstelement.c index f73ca65..c2d46c6 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -53,7 +53,7 @@ enum { }; extern void __gst_element_details_clear (GstElementDetails *dp); -extern void __gst_element_details_set (GstElementDetails *dest, +extern void __gst_element_details_copy (GstElementDetails *dest, const GstElementDetails *src); static void gst_element_class_init (GstElementClass *klass); @@ -172,6 +172,7 @@ gst_element_base_class_init (gpointer g_class) gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_element_real_set_property); gobject_class->get_property = GST_DEBUG_FUNCPTR(gst_element_real_get_property); + memset (&element_class->details, 0, sizeof (GstElementDetails)); element_class->padtemplates = NULL; } @@ -1382,7 +1383,7 @@ gst_element_class_set_details (GstElementClass *klass, const GstElementDetails * g_return_if_fail (GST_IS_ELEMENT_CLASS (klass)); g_return_if_fail (GST_IS_ELEMENT_DETAILS (details)); - __gst_element_details_set (&klass->details, details); + __gst_element_details_copy (&klass->details, details); } /** @@ -2756,6 +2757,7 @@ gst_element_clear_pad_caps (GstElement *element) GstPad *pad = GST_PAD (pads->data); gst_pad_unnegotiate (pad); + gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), NULL); pads = g_list_next (pads); } diff --git a/gst/gstpad.c b/gst/gstpad.c index 0fb5331..b229f07 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -1539,9 +1539,12 @@ gst_pad_can_link_filtered (GstPad *srcpad, GstPad *sinkpad, if (filtercaps) link->filtercaps = gst_caps_copy (filtercaps); gst_pad_link_intersect (link); - if (gst_caps_is_empty (link->caps)) + if (gst_caps_is_empty (link->caps)) { + gst_pad_link_free (link); return FALSE; + } + gst_pad_link_free (link); return TRUE; } @@ -2716,6 +2719,11 @@ gst_real_pad_dispose (GObject *object) gst_element_remove_pad (GST_ELEMENT (GST_OBJECT_PARENT (pad)), pad); } + if (GST_RPAD_EXPLICIT_CAPS (pad)) { + GST_ERROR_OBJECT (pad, "still explicit caps %"GST_PTR_FORMAT" set", GST_RPAD_EXPLICIT_CAPS (pad)); + g_warning ("pad %p has still explicit caps set", pad); + gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), NULL); + } G_OBJECT_CLASS (real_pad_parent_class)->dispose (object); } diff --git a/gst/gststructure.c b/gst/gststructure.c index d593371..7e1cb0e 100644 --- a/gst/gststructure.c +++ b/gst/gststructure.c @@ -237,8 +237,6 @@ void gst_structure_free(GstStructure *structure) GstStructureField *field; int i; - return; - g_return_if_fail(structure != NULL); for(i=0;ifields->len;i++){ @@ -1337,9 +1335,8 @@ gst_structure_from_string (const gchar *string, gchar **end) char *w; char *r; char save; - GstStructure *structure; + GstStructure *structure = NULL; GstStructureField field = { 0 }; - gboolean res; g_return_val_if_fail(string != NULL, NULL); @@ -1347,11 +1344,11 @@ gst_structure_from_string (const gchar *string, gchar **end) r = copy; name = r; - res = _gst_structure_parse_string (r, &w, &r); - if (!res) return NULL; + if (!_gst_structure_parse_string (r, &w, &r)) + goto error; while (g_ascii_isspace(*r)) r++; - if(*r != 0 && *r != ';' && *r != ',') return NULL; + if(*r != 0 && *r != ';' && *r != ',') goto error; save = *w; *w = 0; @@ -1359,24 +1356,28 @@ gst_structure_from_string (const gchar *string, gchar **end) *w = save; while (*r && (*r != ';')){ - if(*r != ',') { - return NULL; - } + if(*r != ',') + goto error; r++; while (*r && g_ascii_isspace(*r)) r++; memset(&field,0,sizeof(field)); - res = _gst_structure_parse_field (r, &r, &field); - if (!res) { - gst_structure_free (structure); - return NULL; - } + if (!_gst_structure_parse_field (r, &r, &field)) + goto error; gst_structure_set_field(structure, &field); while (*r && g_ascii_isspace(*r)) r++; } if (end) *end = (char *)string + (r - copy); + + g_free (copy); return structure; + +error: + if (structure) + gst_structure_free (structure); + g_free (copy); + return NULL; } static void diff --git a/plugins/elements/gsttypefind.c b/plugins/elements/gsttypefind.c index 384b9bd..1ffdfbc 100644 --- a/plugins/elements/gsttypefind.c +++ b/plugins/elements/gsttypefind.c @@ -124,7 +124,7 @@ gst_type_find_element_have_type (GstTypeFindElement *typefind, guint probability GST_INFO_OBJECT (typefind, "found caps %" GST_PTR_FORMAT, caps); typefind->caps = gst_caps_copy (caps); - gst_pad_set_explicit_caps (typefind->src, gst_caps_copy(caps)); + gst_pad_set_explicit_caps (typefind->src, caps); } static void gst_type_find_element_base_init (gpointer g_class) @@ -282,6 +282,12 @@ typedef struct { GList * buffers; GstTypeFindElement * self; } TypeFindEntry; + +static inline TypeFindEntry * +new_entry (void) +{ + return g_new0 (TypeFindEntry, 1); +} static void free_entry_buffers (TypeFindEntry *entry) { @@ -499,7 +505,7 @@ gst_type_find_element_chain (GstPad *pad, GstData *data) all_factories = g_list_sort (all_factories, compare_type_find_factory); walk = all_factories; while (all_factories) { - entry = g_new0 (TypeFindEntry, 1); + entry = new_entry (); entry->factory = GST_TYPE_FIND_FACTORY (all_factories->data); entry->self = typefind; @@ -530,7 +536,6 @@ gst_type_find_element_chain (GstPad *pad, GstData *data) GstCaps *found_caps = entry->caps; guint probability = entry->probability; - found_caps = gst_caps_copy (found_caps); GST_INFO_OBJECT (typefind, "'%s' returned %u/%u probability, using it NOW", GST_PLUGIN_FEATURE_NAME (entry->factory), probability, typefind->max_probability); while (walk) { @@ -545,7 +550,7 @@ gst_type_find_element_chain (GstPad *pad, GstData *data) typefind->possibilities = NULL; g_list_free (typefind->possibilities); g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0, probability, found_caps); - gst_caps_free (found_caps); + free_entry (entry); } else { typefind->possibilities = g_list_prepend (typefind->possibilities, entry); } -- 2.7.4