[gtk+] Bug 659022 - gtk_tree_model_filter_clear_cache_helper: assertion failed



commit bbc1e883a860fab04f230043bffbf3e4c78f66ef
Author: Kristian Rietveld <kris gtk org>
Date:   Mon Oct 3 22:38:42 2011 +0200

    Bug 659022 - gtk_tree_model_filter_clear_cache_helper: assertion failed
    
    This bug is resolved by fixing two things in
    gtk_tree_model_filter_row_deleted():
    
      (1) It is possible for an elt to have elt->visible_siter == NULL, when
      it is deleted.  Only call g_sequence_remove() if this pointer is
      non-NULL.
    
      (2) For the case len (level->seq) > 1, free the elt->children level
      if non-NULL.  Failing to do this means the level will stick around.
      If this child level was not referenced, it will still have a zero
      ref count on its parent which cannot be removed!
    
    For both bugs unit tests have been added in the preceding commit.

 gtk/gtktreemodelfilter.c |   37 +++++++++++++++++++------------------
 1 files changed, 19 insertions(+), 18 deletions(-)
---
diff --git a/gtk/gtktreemodelfilter.c b/gtk/gtktreemodelfilter.c
index e5e4955..daa490b 100644
--- a/gtk/gtktreemodelfilter.c
+++ b/gtk/gtktreemodelfilter.c
@@ -2614,20 +2614,21 @@ gtk_tree_model_filter_row_deleted (GtkTreeModel *c_model,
     gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (data), &iter,
                                            TRUE, FALSE);
 
+  if (elt->children)
+    /* If this last node has children, then the recursion in free_level
+     * will release this reference.
+     */
+    while (elt->ref_count > 1)
+      gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (data), &iter,
+                                             FALSE, FALSE);
+  else
+    while (elt->ref_count > 0)
+      gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (data), &iter,
+                                             FALSE, FALSE);
+
+
   if (g_sequence_get_length (level->seq) == 1)
     {
-      if (elt->children)
-        /* If this last node has children, then the recursion in free_level
-         * will release this reference.
-         */
-        while (elt->ref_count > 1)
-          gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (data), &iter,
-                                                 FALSE, FALSE);
-      else
-        while (elt->ref_count > 0)
-          gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (data), &iter,
-                                                 FALSE, FALSE);
-
       /* kill level */
       gtk_tree_model_filter_free_level (filter, level, FALSE, TRUE, FALSE);
     }
@@ -2636,16 +2637,16 @@ gtk_tree_model_filter_row_deleted (GtkTreeModel *c_model,
       GSequenceIter *tmp;
       gboolean is_first;
 
-      /* Release last references, if needed */
-      while (elt->ref_count > 0)
-        gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (data), &iter,
-                                               FALSE, FALSE);
-
       lookup_elt_with_offset (level->seq, elt->offset, &siter);
       is_first = g_sequence_get_begin_iter (level->seq) == siter;
 
+      if (elt->children)
+        gtk_tree_model_filter_free_level (filter, elt->children,
+                                          FALSE, TRUE, FALSE);
+
       /* remove the row */
-      g_sequence_remove (elt->visible_siter);
+      if (elt->visible_siter)
+        g_sequence_remove (elt->visible_siter);
       tmp = g_sequence_iter_next (siter);
       g_sequence_remove (siter);
       g_sequence_foreach_range (tmp, g_sequence_get_end_iter (level->seq),



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