[gimp] app: make GimpTaggedContainer properly memory manage the filter list



commit aec66d0c267c3061d5de84c17f3d3d810068b8e4
Author: Michael Natterer <mitch gimp org>
Date:   Thu Mar 24 12:28:45 2011 +0100

    app: make GimpTaggedContainer properly memory manage the filter list
    
    instead of leaking it. Also make the fact that tags in the list can
    validly be NULL obvious by adding utility functions
    gimp_tag_or_null_ref/unref().

 app/core/gimptag.c             |   34 ++++++++++++++++++++++++++++++++++
 app/core/gimptag.h             |    3 +++
 app/core/gimptaggedcontainer.c |   29 ++++++++++++++++++++++++++---
 app/widgets/gimptagentry.c     |    2 ++
 4 files changed, 65 insertions(+), 3 deletions(-)
---
diff --git a/app/core/gimptag.c b/app/core/gimptag.c
index f4a65fc..13e8b7c 100644
--- a/app/core/gimptag.c
+++ b/app/core/gimptag.c
@@ -335,3 +335,37 @@ gimp_tag_is_tag_separator (gunichar c)
       return FALSE;
     }
 }
+
+/**
+ * gimp_tag_or_null_ref:
+ * @tag: a #GimpTag
+ *
+ * A simple wrapper around g_object_ref() that silently accepts #NULL.
+ **/
+void
+gimp_tag_or_null_ref (GimpTag *tag_or_null)
+{
+  if (tag_or_null)
+    {
+      g_return_if_fail (GIMP_IS_TAG (tag_or_null));
+
+      g_object_ref (tag_or_null);
+    }
+}
+
+/**
+ * gimp_tag_or_null_unref:
+ * @tag: a #GimpTag
+ *
+ * A simple wrapper around g_object_unref() that silently accepts #NULL.
+ **/
+void
+gimp_tag_or_null_unref (GimpTag *tag_or_null)
+{
+  if (tag_or_null)
+    {
+      g_return_if_fail (GIMP_IS_TAG (tag_or_null));
+
+      g_object_unref (tag_or_null);
+    }
+}
diff --git a/app/core/gimptag.h b/app/core/gimptag.h
index c2b96b7..dcdbaff 100644
--- a/app/core/gimptag.h
+++ b/app/core/gimptag.h
@@ -64,5 +64,8 @@ gint          gimp_tag_compare_with_string (GimpTag        *tag,
 gchar       * gimp_tag_string_make_valid   (const gchar    *tag_string);
 gboolean      gimp_tag_is_tag_separator    (gunichar        c);
 
+void          gimp_tag_or_null_ref         (GimpTag        *tag_or_null);
+void          gimp_tag_or_null_unref       (GimpTag        *tag_or_null);
+
 
 #endif /* __GIMP_TAG_H__ */
diff --git a/app/core/gimptaggedcontainer.c b/app/core/gimptaggedcontainer.c
index d1ab9bd..2676296 100644
--- a/app/core/gimptaggedcontainer.c
+++ b/app/core/gimptaggedcontainer.c
@@ -116,6 +116,13 @@ gimp_tagged_container_dispose (GObject *object)
 {
   GimpTaggedContainer *tagged_container = GIMP_TAGGED_CONTAINER (object);
 
+  if (tagged_container->filter)
+    {
+      g_list_free_full (tagged_container->filter,
+                        (GDestroyNotify) gimp_tag_or_null_unref);
+      tagged_container->filter = NULL;
+    }
+
   if (tagged_container->tag_ref_counts)
     {
       g_hash_table_unref (tagged_container->tag_ref_counts);
@@ -251,7 +258,7 @@ gimp_tagged_container_new (GimpContainer *src_container)
 /**
  * gimp_tagged_container_set_filter:
  * @tagged_container: a #GimpTaggedContainer object.
- * @tags:               list of #GimpTag objects.
+ * @tags:             list of #GimpTag objects.
  *
  * Sets list of tags to be used for filtering. Only objects which have
  * all of the tags assigned match filtering criteria.
@@ -260,14 +267,30 @@ void
 gimp_tagged_container_set_filter (GimpTaggedContainer *tagged_container,
                                   GList               *tags)
 {
+  GList *new_filter;
+
   g_return_if_fail (GIMP_IS_TAGGED_CONTAINER (tagged_container));
 
+  if (tags)
+    {
+      GList *list;
+
+      for (list = tags; list; list = g_list_next (list))
+        g_return_if_fail (list->data == NULL || GIMP_IS_TAG (list->data));
+    }
+
   if (! gimp_container_frozen (GIMP_FILTERED_CONTAINER (tagged_container)->src_container))
     {
       gimp_tagged_container_src_freeze (GIMP_FILTERED_CONTAINER (tagged_container));
     }
 
-  tagged_container->filter = tags;
+  /*  ref new tags first, they could be the same as the old ones  */
+  new_filter = g_list_copy (tags);
+  g_list_foreach (new_filter, (GFunc) gimp_tag_or_null_ref, NULL);
+
+  g_list_free_full (tagged_container->filter,
+                    (GDestroyNotify) gimp_tag_or_null_unref);
+  tagged_container->filter = new_filter;
 
   if (! gimp_container_frozen (GIMP_FILTERED_CONTAINER (tagged_container)->src_container))
     {
@@ -283,7 +306,7 @@ gimp_tagged_container_set_filter (GimpTaggedContainer *tagged_container,
  * must be contained by each object matching filter criteria.
  *
  * Return value: a list of GimpTag objects used as filter. This value should
- * not be modified or freed.
+ *               not be modified or freed.
  **/
 const GList *
 gimp_tagged_container_get_filter (GimpTaggedContainer *tagged_container)
diff --git a/app/widgets/gimptagentry.c b/app/widgets/gimptagentry.c
index 6c7e879..712907c 100644
--- a/app/widgets/gimptagentry.c
+++ b/app/widgets/gimptagentry.c
@@ -623,6 +623,8 @@ gimp_tag_entry_query_tag (GimpTagEntry *entry)
   gimp_tagged_container_set_filter (GIMP_TAGGED_CONTAINER (entry->container),
                                     query_list);
 
+  g_list_free_full (query_list, (GDestroyNotify) gimp_tag_or_null_unref);
+
   if (has_invalid_tags != entry->has_invalid_tags)
     {
       entry->has_invalid_tags = has_invalid_tags;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]