[evolution] ** BUGFIX: 569696 – Memory leak in message-list



commit fad86a267fd3c0ebc402ca67f14a0d2f74f57b74
Author: Srinivasa Ragavan <sragavan novell com>
Date:   Mon May 4 09:40:18 2009 +0530

    ** BUGFIX: 569696 â?? Memory leak in message-list
    
    Not exactly a leak, but a build-up over a period of time.
    Clear the internal gnode on regen.
---
 mail/message-list.c                  |   11 ++++++-----
 widgets/table/e-tree-model.c         |   30 ++++++++++++++++++++++++++++++
 widgets/table/e-tree-model.h         |    2 ++
 widgets/table/e-tree-table-adapter.c |   27 +++++++++++++++++++++++++++
 4 files changed, 65 insertions(+), 5 deletions(-)

diff --git a/mail/message-list.c b/mail/message-list.c
index 3027fcf..6817753 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -2584,7 +2584,7 @@ clear_info(char *key, ETreePath *node, MessageList *ml)
 }
 
 static void
-clear_tree (MessageList *ml)
+clear_tree (MessageList *ml, gboolean tfree)
 {
 	ETreeModel *etm = ml->model;
 
@@ -2608,7 +2608,8 @@ clear_tree (MessageList *ml)
 	}
 
 	ml->tree_root = e_tree_memory_node_insert (E_TREE_MEMORY(etm), NULL, 0, NULL);
-
+	if (tfree)
+		e_tree_model_rebuilt (E_TREE_MODEL(etm));	
 #ifdef TIMEIT
 	gettimeofday(&end, NULL);
 	diff = end.tv_sec * 1000 + end.tv_usec/1000;
@@ -2769,7 +2770,7 @@ build_tree (MessageList *ml, CamelFolderThread *thread, CamelFolderChangeInfo *c
 		selected = message_list_get_selected(ml);
 #endif
 		e_tree_memory_freeze(E_TREE_MEMORY(etm));
-		clear_tree (ml);
+		clear_tree (ml, FALSE);
 
 		build_subtree(ml, ml->tree_root, thread->tree, &row);
 		e_tree_memory_thaw(E_TREE_MEMORY(etm));
@@ -3088,7 +3089,7 @@ build_flat (MessageList *ml, GPtrArray *summary, CamelFolderChangeInfo *changes)
 		selected = message_list_get_selected(ml);
 #endif
 		e_tree_memory_freeze(E_TREE_MEMORY(etm));
-		clear_tree (ml);
+		clear_tree (ml, FALSE);
 		for (i = 0; i < summary->len; i++) {
 			ETreePath node;
 			CamelMessageInfo *info = summary->pdata[i];
@@ -3354,7 +3355,7 @@ message_list_set_folder (MessageList *message_list, CamelFolder *folder, const c
 	}
 
 	e_tree_memory_freeze(E_TREE_MEMORY(etm));
-	clear_tree (message_list);
+	clear_tree (message_list, TRUE);
 	e_tree_memory_thaw(E_TREE_MEMORY(etm));
 
 	if (message_list->folder) {
diff --git a/widgets/table/e-tree-model.c b/widgets/table/e-tree-model.c
index 10c7afe..b2e2d99 100644
--- a/widgets/table/e-tree-model.c
+++ b/widgets/table/e-tree-model.c
@@ -53,6 +53,7 @@ enum {
 	NODE_REMOVED,
 	NODE_DELETED,
 	NODE_REQUEST_COLLAPSE,
+	REBUILT,
 	LAST_SIGNAL
 };
 
@@ -82,6 +83,15 @@ e_tree_model_class_init (ETreeModelClass *klass)
 			      g_cclosure_marshal_VOID__VOID,
 			      G_TYPE_NONE, 0);
 
+	e_tree_model_signals [REBUILT] =
+		g_signal_new ("rebuilt",
+			      G_TYPE_FROM_CLASS (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (ETreeModelClass, rebuilt),
+			      (GSignalAccumulator) NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE, 0);
+
 	e_tree_model_signals [NODE_CHANGED] =
 		g_signal_new ("node_changed",
 			      G_TYPE_FROM_CLASS (object_class),
@@ -183,6 +193,7 @@ e_tree_model_class_init (ETreeModelClass *klass)
 
 	klass->pre_change            = NULL;
 	klass->no_change             = NULL;
+	klass->rebuilt	             = NULL;
 	klass->node_changed          = NULL;
 	klass->node_data_changed     = NULL;
 	klass->node_col_changed      = NULL;
@@ -241,6 +252,25 @@ e_tree_model_no_change  (ETreeModel *tree_model)
 }
 
 /**
+ * e_tree_model_rebuilt:
+ * @tree_model:
+ * @node:
+ *
+ *
+ *
+ * Return value:
+ **/
+void
+e_tree_model_rebuilt  (ETreeModel *tree_model)
+{
+	g_return_if_fail (tree_model != NULL);
+	g_return_if_fail (E_IS_TREE_MODEL (tree_model));
+
+	d(g_print("Emitting rebuilt on model 0x%p, a %s.\n", tree_model, g_type_name (GTK_OBJECT(tree_model)->klass->type)));
+
+	g_signal_emit (G_OBJECT (tree_model), e_tree_model_signals [REBUILT], 0);
+}
+/**
  * e_tree_model_node_changed:
  * @tree_model:
  * @node:
diff --git a/widgets/table/e-tree-model.h b/widgets/table/e-tree-model.h
index a318bd7..96828a8 100644
--- a/widgets/table/e-tree-model.h
+++ b/widgets/table/e-tree-model.h
@@ -112,6 +112,7 @@ struct ETreeModelClass {
 	void       (*node_inserted)         (ETreeModel *etm, ETreePath parent, ETreePath inserted_node);
 	void       (*node_removed)          (ETreeModel *etm, ETreePath parent, ETreePath removed_node, int old_position);
 	void       (*node_deleted)          (ETreeModel *etm, ETreePath deleted_node);
+	void       (*rebuilt)          (ETreeModel *etm);
 
 	/* This signal requests that any viewers of the tree that
 	 * collapse and expand nodes collapse this node.
@@ -206,6 +207,7 @@ ETreePath   e_tree_model_node_find               (ETreeModel     *model,
 */
 void        e_tree_model_pre_change              (ETreeModel     *tree_model);
 void        e_tree_model_no_change               (ETreeModel     *tree_model);
+void        e_tree_model_rebuilt                 (ETreeModel     *tree_model);
 void        e_tree_model_node_changed            (ETreeModel     *tree_model,
 						  ETreePath       node);
 void        e_tree_model_node_data_changed       (ETreeModel     *tree_model,
diff --git a/widgets/table/e-tree-table-adapter.c b/widgets/table/e-tree-table-adapter.c
index 7e63a64..10c29fb 100644
--- a/widgets/table/e-tree-table-adapter.c
+++ b/widgets/table/e-tree-table-adapter.c
@@ -72,6 +72,7 @@ struct ETreeTableAdapterPriv {
 
 	int          pre_change_id;
 	int          no_change_id;
+	int	     rebuilt_id;
 	int          node_changed_id;
 	int          node_data_changed_id;
 	int          node_col_changed_id;
@@ -543,6 +544,8 @@ etta_dispose (GObject *object)
 		g_signal_handler_disconnect (G_OBJECT (etta->priv->source),
 				       etta->priv->no_change_id);
 		g_signal_handler_disconnect (G_OBJECT (etta->priv->source),
+				       etta->priv->rebuilt_id);
+		g_signal_handler_disconnect (G_OBJECT (etta->priv->source),
 				       etta->priv->node_changed_id);
 		g_signal_handler_disconnect (G_OBJECT (etta->priv->source),
 				       etta->priv->node_data_changed_id);
@@ -730,6 +733,7 @@ etta_init (ETreeTableAdapter *etta)
 
 	etta->priv->pre_change_id            = 0;
 	etta->priv->no_change_id             = 0;
+	etta->priv->rebuilt_id		     = 0;
 	etta->priv->node_changed_id          = 0;
 	etta->priv->node_data_changed_id     = 0;
 	etta->priv->node_col_changed_id      = 0;
@@ -754,6 +758,27 @@ etta_proxy_no_change (ETreeModel *etm, ETreeTableAdapter *etta)
 }
 
 static gboolean
+remove_all (gpointer key, gpointer value, gpointer data)
+{
+	GNode *gn = (GNode *) data;
+	if (data)
+		g_free (gn->data);
+
+	return TRUE;
+}
+
+static void
+etta_proxy_rebuilt (ETreeModel *etm, ETreeTableAdapter *etta)
+{
+	if (!etta->priv->root)
+		return;
+	kill_gnode (etta->priv->root, etta);
+	etta->priv->root = NULL;
+	g_hash_table_destroy (etta->priv->nodes);
+	etta->priv->nodes = g_hash_table_new(NULL, NULL);
+}
+
+static gboolean
 resort_model (ETreeTableAdapter *etta)
 {
 	etta_sort_info_changed (NULL, etta);
@@ -866,6 +891,8 @@ e_tree_table_adapter_construct (ETreeTableAdapter *etta, ETreeModel *source, ETa
 					G_CALLBACK (etta_proxy_pre_change), etta);
 	etta->priv->no_change_id = g_signal_connect (G_OBJECT (source), "no_change",
 					G_CALLBACK (etta_proxy_no_change), etta);
+	etta->priv->rebuilt_id = g_signal_connect (G_OBJECT (source), "rebuilt",
+					G_CALLBACK (etta_proxy_rebuilt), etta);
 	etta->priv->node_changed_id = g_signal_connect (G_OBJECT (source), "node_changed",
 					G_CALLBACK (etta_proxy_node_changed), etta);
 	etta->priv->node_data_changed_id = g_signal_connect (G_OBJECT (source), "node_data_changed",



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