diff options
author | Milan Crha <mcrha@redhat.com> | 2014-02-21 03:12:30 +0800 |
---|---|---|
committer | Milan Crha <mcrha@redhat.com> | 2014-02-21 03:12:30 +0800 |
commit | 967d37373f5e59a46203cd84ee84650928771143 (patch) | |
tree | a9fd77c258601035f007a28e1d719dda08e4bdf5 /mail/em-folder-tree-model.c | |
parent | 197c8e1274f70c035614cbb54c7926901d1b1db5 (diff) | |
download | gsoc2013-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.c | 30 |
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) { |