various cleanups and memleak plugging. make valgrind is happy now.
authorThomas Vander Stichele <thomas@apestaart.org>
Sun, 18 Sep 2005 21:24:55 +0000 (21:24 +0000)
committerThomas Vander Stichele <thomas@apestaart.org>
Sun, 18 Sep 2005 21:24:55 +0000 (21:24 +0000)
Original commit message from CVS:
various cleanups and memleak plugging.  make valgrind is happy now.

12 files changed:
ChangeLog
check/gst/gst.c
gst/gst.c
gst/gstelementfactory.c
gst/gstindex.c
gst/gstobject.c
gst/gstplugin.c
gst/gstpluginfeature.c
gst/gstregistry.c
gst/gstregistry.h
gst/gstregistryxml.c
tests/check/gst/gst.c

index 8729a2d..74ff137 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
 2005-09-18  Thomas Vander Stichele  <thomas at apestaart dot org>
 
+       * 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  <thomas at apestaart dot org>
+
        * common/check.mak:
          add a check-valgrind target
 
index 993c633..f839677 100644 (file)
@@ -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);
 }
 
index 11ee8d6..4ff0b69 100644 (file)
--- 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;
 }
 
index 180d301..ac404d6 100644 (file)
@@ -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);
index 1ddd0b0..f592b09 100644 (file)
@@ -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
index 5a88620..ed53ece 100644 (file)
@@ -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 */
index 3cc6bcd..1cec9bb 100644 (file)
@@ -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:
index 795a5ad..04f74a1 100644 (file)
 
 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);
 }
 
 /**
index 531a7fc..d9bcdf5 100644 (file)
@@ -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;
+}
index 359d1cb..9223f8f 100644 (file)
@@ -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) \
index ea84ea0..b1393b3 100644 (file)
@@ -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");
 
index 993c633..f839677 100644 (file)
@@ -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);
 }