From 87ec30aa38126c67f686ea92ffda9d2993bf08a9 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 18 Sep 2005 21:24:55 +0000 Subject: [PATCH] various cleanups and memleak plugging. make valgrind is happy now. Original commit message from CVS: various cleanups and memleak plugging. make valgrind is happy now. --- ChangeLog | 19 ++++++++++++ check/gst/gst.c | 2 +- gst/gst.c | 5 ++++ gst/gstelementfactory.c | 17 ++++++++++- gst/gstindex.c | 14 +++++++++ gst/gstobject.c | 4 +-- gst/gstplugin.c | 17 ++++++++--- gst/gstpluginfeature.c | 14 +++++++-- gst/gstregistry.c | 64 +++++++++++++++++++++++++++++++++++++++-- gst/gstregistry.h | 2 ++ gst/gstregistryxml.c | 24 ++++++++++++---- tests/check/gst/gst.c | 2 +- 12 files changed, 163 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8729a2ddad..74ff137093 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2005-09-18 Thomas Vander Stichele + + * gst/gst.c: (init_post), (gst_deinit): + * gst/gstelementfactory.c: (gst_element_factory_class_init), + (gst_element_factory_finalize), (gst_element_factory_cleanup): + * gst/gstindex.c: (gst_index_factory_class_init), + (gst_index_factory_finalize): + * gst/gstobject.c: (gst_object_dispose): + * gst/gstplugin.c: (gst_plugin_finalize), (gst_plugin_class_init), + (gst_plugin_load_file), (gst_plugin_desc_free): + * gst/gstpluginfeature.c: (gst_plugin_feature_class_init), + (gst_plugin_feature_finalize): + * gst/gstregistry.c: (gst_registry_class_init), + (gst_registry_init), (gst_registry_finalize), + (gst_registry_get_default), (gst_registry_deinit): + * gst/gstregistry.h: + * gst/gstregistryxml.c: (load_feature), (load_plugin): + various cleanups and memleak plugging. make valgrind is happy now. + 2005-09-18 Thomas Vander Stichele * common/check.mak: diff --git a/check/gst/gst.c b/check/gst/gst.c index 993c6330c8..f839677755 100644 --- a/check/gst/gst.c +++ b/check/gst/gst.c @@ -25,7 +25,7 @@ GST_START_TEST (test_init) { /* don't segfault with NULL, NULL */ gst_init (NULL, NULL); - /* allow calling twice */ + /* allow calling twice. well, actually, thrice. */ gst_init (NULL, NULL); } diff --git a/gst/gst.c b/gst/gst.c index 11ee8d6f6f..4ff0b696e0 100644 --- a/gst/gst.c +++ b/gst/gst.c @@ -731,6 +731,7 @@ init_post (void) for (i = 0; list[i]; i++) { gst_registry_scan_path (default_registry, list[i]); } + g_strfreev (list); } gst_registry_xml_write_cache (default_registry, registry_file); @@ -904,6 +905,8 @@ init_popt_callback (poptContext context, enum poptCallbackReason reason, * Call only once, before exiting. * After this call GStreamer should not be used anymore. */ + +extern GstRegistry *_gst_registry_default; void gst_deinit (void) { @@ -913,6 +916,8 @@ gst_deinit (void) gst_object_unref (clock); gst_object_unref (clock); + gst_registry_deinit (); + gst_initialized = FALSE; } diff --git a/gst/gstelementfactory.c b/gst/gstelementfactory.c index 180d3010ab..ac404d6eb6 100644 --- a/gst/gstelementfactory.c +++ b/gst/gstelementfactory.c @@ -76,6 +76,9 @@ GST_DEBUG_CATEGORY_STATIC (element_factory_debug); static void gst_element_factory_class_init (GstElementFactoryClass * klass); static void gst_element_factory_init (GstElementFactory * factory); +static void gst_element_factory_finalize (GObject * object); +void __gst_element_details_clear (GstElementDetails * dp); +static void gst_element_factory_cleanup (GstElementFactory * factory); static GstPluginFeatureClass *parent_class = NULL; @@ -121,7 +124,9 @@ gst_element_factory_class_init (GstElementFactoryClass * klass) parent_class = g_type_class_peek_parent (klass); + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_element_factory_finalize); } + static void gst_element_factory_init (GstElementFactory * factory) { @@ -134,6 +139,15 @@ gst_element_factory_init (GstElementFactory * factory) factory->interfaces = NULL; } +static void +gst_element_factory_finalize (GObject * object) +{ + GstElementFactory *factory = GST_ELEMENT_FACTORY (object); + + gst_element_factory_cleanup (factory); + G_OBJECT_CLASS (parent_class)->finalize (object); +} + /** * gst_element_factory_find: * @name: name of factory to find @@ -217,7 +231,8 @@ gst_element_factory_cleanup (GstElementFactory * factory) GstStaticPadTemplate *templ = item->data; g_free (templ->name_template); - /* FIXME: free caps... */ + g_free ((gchar *) templ->static_caps.string); + memset (&(templ->static_caps), 0, sizeof (GstStaticCaps)); g_free (templ); } g_list_free (factory->staticpadtemplates); diff --git a/gst/gstindex.c b/gst/gstindex.c index 1ddd0b0bb4..f592b0979e 100644 --- a/gst/gstindex.c +++ b/gst/gstindex.c @@ -849,6 +849,7 @@ gst_index_entry_assoc_map (GstIndexEntry * entry, static void gst_index_factory_class_init (GstIndexFactoryClass * klass); static void gst_index_factory_init (GstIndexFactory * factory); +static void gst_index_factory_finalize (GObject * object); static GstPluginFeatureClass *factory_parent_class = NULL; @@ -891,6 +892,8 @@ gst_index_factory_class_init (GstIndexFactoryClass * klass) gstpluginfeature_class = (GstPluginFeatureClass *) klass; factory_parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE); + + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_index_factory_finalize); } static void @@ -898,6 +901,17 @@ gst_index_factory_init (GstIndexFactory * factory) { } +static void +gst_index_factory_finalize (GObject * object) +{ + GstIndexFactory *factory = GST_INDEX_FACTORY (object); + + g_free (factory->longdesc); + + G_OBJECT_CLASS (factory_parent_class)->finalize (object); + +} + /** * gst_index_factory_new: * @name: name of indexfactory to create diff --git a/gst/gstobject.c b/gst/gstobject.c index 5a88620831..ed53ece015 100644 --- a/gst/gstobject.c +++ b/gst/gstobject.c @@ -421,9 +421,9 @@ gst_object_dispose (GObject * object) GST_UNLOCK (object); /* need to patch refcount so it is finalized */ - PATCH_REFCOUNT1 (object) + PATCH_REFCOUNT1 (object); - parent_class->dispose (object); + parent_class->dispose (object); } /* finalize is called when the object has to free its resources */ diff --git a/gst/gstplugin.c b/gst/gstplugin.c index 3cc6bcd394..1cec9bb33f 100644 --- a/gst/gstplugin.c +++ b/gst/gstplugin.c @@ -78,10 +78,13 @@ static GstPlugin *gst_plugin_register_func (GstPlugin * plugin, GModule * module, GstPluginDesc * desc); static void gst_plugin_desc_copy (GstPluginDesc * dest, const GstPluginDesc * src); +static void gst_plugin_desc_free (GstPluginDesc * desc); G_DEFINE_TYPE (GstPlugin, gst_plugin, GST_TYPE_OBJECT); +static GstObjectClass *parent_class = NULL; + static void gst_plugin_init (GstPlugin * plugin) { @@ -89,8 +92,9 @@ gst_plugin_init (GstPlugin * plugin) } static void -gst_plugin_finalize (GstPlugin * plugin) +gst_plugin_finalize (GObject * object) { + GstPlugin *plugin = GST_PLUGIN (object); GstRegistry *registry = gst_registry_get_default (); GList *g; @@ -100,13 +104,18 @@ gst_plugin_finalize (GstPlugin * plugin) g_warning ("removing plugin that is still in registry"); } } + g_free (plugin->filename); + gst_plugin_desc_free (&plugin->desc); + + G_OBJECT_CLASS (parent_class)->finalize (object); } static void gst_plugin_class_init (GstPluginClass * klass) { + parent_class = g_type_class_ref (GST_TYPE_OBJECT); - G_OBJECT_CLASS (klass)->finalize = (GObjectFinalizeFunc) gst_plugin_finalize; + G_OBJECT_CLASS (klass)->finalize = GST_DEBUG_FUNCPTR (gst_plugin_finalize); } GQuark @@ -425,6 +434,8 @@ gst_plugin_load_file (const gchar * filename, GError ** error) g_static_mutex_unlock (&gst_plugin_loading_mutex); return plugin; return_error: + if (plugin) + gst_object_unref (plugin); g_static_mutex_unlock (&gst_plugin_loading_mutex); return NULL; } @@ -444,7 +455,6 @@ gst_plugin_desc_copy (GstPluginDesc * dest, const GstPluginDesc * src) dest->origin = g_strdup (src->origin); } -#if 0 /* unused */ static void gst_plugin_desc_free (GstPluginDesc * desc) @@ -459,7 +469,6 @@ gst_plugin_desc_free (GstPluginDesc * desc) memset (desc, 0, sizeof (GstPluginDesc)); } -#endif /** * gst_plugin_get_name: diff --git a/gst/gstpluginfeature.c b/gst/gstpluginfeature.c index 795a5adcdb..04f74a1da0 100644 --- a/gst/gstpluginfeature.c +++ b/gst/gstpluginfeature.c @@ -31,18 +31,20 @@ static void gst_plugin_feature_class_init (GstPluginFeatureClass * klass); static void gst_plugin_feature_init (GstPluginFeature * feature); -static void gst_plugin_feature_finalize (GstPluginFeature * feature); +static void gst_plugin_feature_finalize (GObject * object); /* static guint gst_plugin_feature_signals[LAST_SIGNAL] = { 0 }; */ G_DEFINE_ABSTRACT_TYPE (GstPluginFeature, gst_plugin_feature, GST_TYPE_OBJECT); +GstObjectClass *parent_class = NULL; static void gst_plugin_feature_class_init (GstPluginFeatureClass * klass) { + parent_class = g_type_class_ref (GST_TYPE_OBJECT); G_OBJECT_CLASS (klass)->finalize = - (GObjectFinalizeFunc) gst_plugin_feature_finalize; + GST_DEBUG_FUNCPTR (gst_plugin_feature_finalize); } static void @@ -52,9 +54,15 @@ gst_plugin_feature_init (GstPluginFeature * feature) } static void -gst_plugin_feature_finalize (GstPluginFeature * feature) +gst_plugin_feature_finalize (GObject * object) { + GstPluginFeature *feature = GST_PLUGIN_FEATURE (object); + GST_DEBUG ("finalizing feature %p", feature); + g_free (feature->name); + g_free (feature->plugin_name); + + G_OBJECT_CLASS (parent_class)->finalize (object); } /** diff --git a/gst/gstregistry.c b/gst/gstregistry.c index 531a7fc196..d9bcdf5e16 100644 --- a/gst/gstregistry.c +++ b/gst/gstregistry.c @@ -51,6 +51,9 @@ #define GST_CAT_DEFAULT GST_CAT_REGISTRY +/* the one instance of the default registry */ +static GstRegistry *_gst_registry_default = NULL; + /* * Design: * @@ -117,6 +120,7 @@ enum static void gst_registry_class_init (GstRegistryClass * klass); static void gst_registry_init (GstRegistry * registry); +static void gst_registry_finalize (GObject * object); static guint gst_registry_signals[LAST_SIGNAL] = { 0 }; @@ -126,6 +130,7 @@ static GstPlugin *gst_registry_lookup_locked (GstRegistry * registry, const char *filename); G_DEFINE_TYPE (GstRegistry, gst_registry, GST_TYPE_OBJECT); +static GstObjectClass *parent_class = NULL; static void gst_registry_class_init (GstRegistryClass * klass) @@ -134,6 +139,8 @@ gst_registry_class_init (GstRegistryClass * klass) gobject_class = (GObjectClass *) klass; + parent_class = g_type_class_ref (GST_TYPE_OBJECT); + gst_registry_signals[PLUGIN_ADDED] = g_signal_new ("plugin-added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRegistryClass, plugin_added), NULL, @@ -143,20 +150,61 @@ gst_registry_class_init (GstRegistryClass * klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRegistryClass, feature_added), NULL, NULL, gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); - gobject_class->dispose = NULL; + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_registry_finalize); } static void gst_registry_init (GstRegistry * registry) { +} +static void +gst_registry_finalize (GObject * object) +{ + GstRegistry *registry = GST_REGISTRY (object); + GList *plugins, *p; + GList *features, *f; + + plugins = registry->plugins; + registry->plugins = NULL; + + GST_DEBUG_OBJECT (registry, "registry finalize"); + p = plugins; + while (p) { + GstPlugin *plugin = p->data; + + if (plugin) { + GST_DEBUG_OBJECT (registry, "removing plugin %s", + gst_plugin_get_name (plugin)); + gst_registry_remove_plugin (registry, plugin); + } + p = g_list_next (p); + } + g_list_free (plugins); + + features = registry->features; + registry->features = NULL; + + f = features; + while (f) { + GstPluginFeature *feature = f->data; + + if (feature) { + GST_DEBUG_OBJECT (registry, "removing feature %s", + gst_plugin_feature_get_name (feature)); + gst_registry_remove_feature (registry, feature); + } + f = g_list_next (f); + } + g_list_free (features); + + + G_OBJECT_CLASS (parent_class)->finalize (object); } GstRegistry * gst_registry_get_default (void) { - static GstRegistry *_gst_registry_default; - if (!_gst_registry_default) { _gst_registry_default = g_object_new (GST_TYPE_REGISTRY, NULL); } @@ -700,3 +748,13 @@ gst_registry_get_feature_list_by_plugin (GstRegistry * registry, return gst_registry_feature_filter (registry, _gst_plugin_feature_filter_plugin_name, FALSE, (gpointer) name); } + +void +gst_registry_deinit () +{ + if (!_gst_registry_default) + return; + + gst_object_unref (_gst_registry_default); + _gst_registry_default = NULL; +} diff --git a/gst/gstregistry.h b/gst/gstregistry.h index 359d1cb760..9223f8f062 100644 --- a/gst/gstregistry.h +++ b/gst/gstregistry.h @@ -100,6 +100,8 @@ gboolean gst_registry_xml_write_cache (GstRegistry * registry, const char *locat void gst_registry_scan_paths (GstRegistry *registry); void _gst_registry_remove_cache_plugins (GstRegistry *registry); +void gst_registry_deinit (void); + #define gst_default_registry_add_plugin(plugin) \ gst_registry_add_plugin (gst_registry_get_default(), plugin) #define gst_default_registry_add_path(path) \ diff --git a/gst/gstregistryxml.c b/gst/gstregistryxml.c index ea84ea074f..b1393b3727 100644 --- a/gst/gstregistryxml.c +++ b/gst/gstregistryxml.c @@ -374,6 +374,7 @@ add_to_char_array (gchar *** array, gchar * value) *array = new; } +/* read a string and copy it into the given location */ static gboolean read_string (xmlTextReaderPtr reader, gchar ** write_to) { @@ -502,19 +503,24 @@ load_feature (xmlTextReaderPtr reader) { int ret; int depth = xmlTextReaderDepth (reader); - const gchar *feature_name = - (const gchar *) xmlTextReaderGetAttribute (reader, BAD_CAST "typename"); + gchar *feature_name = + (gchar *) xmlTextReaderGetAttribute (reader, BAD_CAST "typename"); GstPluginFeature *feature; GType type; if (!feature_name) return NULL; type = g_type_from_name (feature_name); - if (!type) + g_free (feature_name); + feature_name = NULL; + + if (!type) { return NULL; + } feature = g_object_new (type, NULL); - if (!feature) + if (!feature) { return NULL; + } if (!GST_IS_PLUGIN_FEATURE (feature)) { g_object_unref (feature); return NULL; @@ -554,6 +560,7 @@ load_feature (xmlTextReaderPtr reader) } else if (g_ascii_strncasecmp (s, "source", 5) == 0) { factory->uri_type = GST_URI_SRC; } + g_free (s); } } else if (g_str_equal (tag, "uri_protocol")) { gchar *s = NULL; @@ -563,8 +570,11 @@ load_feature (xmlTextReaderPtr reader) } else if (g_str_equal (tag, "interface")) { gchar *s = NULL; - if (read_string (reader, &s)) + if (read_string (reader, &s)) { __gst_element_factory_add_interface (factory, s); + /* add_interface strdup's s */ + g_free (s); + } } else if (g_str_equal (tag, "padtemplate")) { GstStaticPadTemplate *template = load_pad_template (reader); @@ -600,6 +610,7 @@ load_feature (xmlTextReaderPtr reader) } } + g_assert_not_reached (); return NULL; } @@ -663,6 +674,7 @@ load_plugin (xmlTextReaderPtr reader, GList ** feature_list) } plugin->file_mtime = strtol (s, NULL, 0); GST_DEBUG ("mtime %d", (int) plugin->file_mtime); + g_free (s); } else if (g_str_equal (tag, "size")) { unsigned int x; @@ -685,7 +697,7 @@ load_plugin (xmlTextReaderPtr reader, GList ** feature_list) } } } - g_object_unref (plugin); + gst_object_unref (plugin); GST_DEBUG ("problem reading plugin"); diff --git a/tests/check/gst/gst.c b/tests/check/gst/gst.c index 993c6330c8..f839677755 100644 --- a/tests/check/gst/gst.c +++ b/tests/check/gst/gst.c @@ -25,7 +25,7 @@ GST_START_TEST (test_init) { /* don't segfault with NULL, NULL */ gst_init (NULL, NULL); - /* allow calling twice */ + /* allow calling twice. well, actually, thrice. */ gst_init (NULL, NULL); }