aboutsummaryrefslogtreecommitdiffstats
path: root/mail/em-folder-tree-model.c
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2014-02-21 03:12:30 +0800
committerMilan Crha <mcrha@redhat.com>2014-02-21 03:12:30 +0800
commit967d37373f5e59a46203cd84ee84650928771143 (patch)
treea9fd77c258601035f007a28e1d719dda08e4bdf5 /mail/em-folder-tree-model.c
parent197c8e1274f70c035614cbb54c7926901d1b1db5 (diff)
downloadgsoc2013-evolution-967d37373f5e59a46203cd84ee84650928771143.tar
gsoc2013-evolution-967d37373f5e59a46203cd84ee84650928771143.tar.gz
gsoc2013-evolution-967d37373f5e59a46203cd84ee84650928771143.tar.bz2
gsoc2013-evolution-967d37373f5e59a46203cd84ee84650928771143.tar.lz
gsoc2013-evolution-967d37373f5e59a46203cd84ee84650928771143.tar.xz
gsoc2013-evolution-967d37373f5e59a46203cd84ee84650928771143.tar.zst
gsoc2013-evolution-967d37373f5e59a46203cd84ee84650928771143.zip
EMFolderTreeModel: Fix a circular dependency between model and its data
The model stores GtkTreeRowReference-s in its private data, but these references ref the model, thus there is a circular dependency between internal data and the object itself, effectively causing memory leaks. With this fixed, the CamelSession is correctly freed at the end of the application.
Diffstat (limited to 'mail/em-folder-tree-model.c')
-rw-r--r--mail/em-folder-tree-model.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/mail/em-folder-tree-model.c b/mail/em-folder-tree-model.c
index 789bb20e38..3597b6ec6c 100644
--- a/mail/em-folder-tree-model.c
+++ b/mail/em-folder-tree-model.c
@@ -844,17 +844,39 @@ em_folder_tree_model_new (void)
return g_object_new (EM_TYPE_FOLDER_TREE_MODEL, NULL);
}
-EMFolderTreeModel *
-em_folder_tree_model_get_default (void)
+static EMFolderTreeModel *
+em_folder_tree_manage_default (gboolean do_create)
{
- static EMFolderTreeModel *default_folder_tree_model;
+ static EMFolderTreeModel *default_folder_tree_model = NULL;
- if (G_UNLIKELY (default_folder_tree_model == NULL))
+ if (do_create && G_UNLIKELY (default_folder_tree_model == NULL)) {
default_folder_tree_model = em_folder_tree_model_new ();
+ } else if (!do_create && G_UNLIKELY (default_folder_tree_model != NULL)) {
+ /* This is necessary, due to circular dependency between stored GtkTreeRwoReference
+ and the model itself. */
+ g_mutex_lock (&default_folder_tree_model->priv->store_index_lock);
+ g_hash_table_remove_all (default_folder_tree_model->priv->store_index);
+ g_mutex_unlock (&default_folder_tree_model->priv->store_index_lock);
+
+ g_object_unref (default_folder_tree_model);
+ default_folder_tree_model = NULL;
+ }
return default_folder_tree_model;
}
+EMFolderTreeModel *
+em_folder_tree_model_get_default (void)
+{
+ return em_folder_tree_manage_default (TRUE);
+}
+
+void
+em_folder_tree_model_free_default (void)
+{
+ em_folder_tree_manage_default (FALSE);
+}
+
GtkTreeSelection *
em_folder_tree_model_get_selection (EMFolderTreeModel *model)
{