[evolution/evolution-3-12] Bug 704663 - Crash under em_folder_tree_model_add_store()



commit 457fea5f700ee9973d04f4c450f16156a6459700
Author: Milan Crha <mcrha redhat com>
Date:   Wed Jun 11 12:50:53 2014 +0200

    Bug 704663 - Crash under em_folder_tree_model_add_store()

 mail/em-folder-selector.c   |    3 +++
 mail/em-folder-tree-model.c |   40 +++++++++++++++++++++++++++++++++++++++-
 mail/em-folder-tree-model.h |    2 ++
 3 files changed, 44 insertions(+), 1 deletions(-)
---
diff --git a/mail/em-folder-selector.c b/mail/em-folder-selector.c
index 87536a0..dbf885a 100644
--- a/mail/em-folder-selector.c
+++ b/mail/em-folder-selector.c
@@ -115,6 +115,9 @@ folder_selector_dispose (GObject *object)
        }
 
        if (emfs->priv->model != NULL) {
+               if (emfs->priv->model && emfs->priv->model != em_folder_tree_model_get_default ())
+                       em_folder_tree_model_remove_all_stores (emfs->priv->model);
+
                g_object_unref (emfs->priv->model);
                emfs->priv->model = NULL;
        }
diff --git a/mail/em-folder-tree-model.c b/mail/em-folder-tree-model.c
index 8bbceab..f64e147 100644
--- a/mail/em-folder-tree-model.c
+++ b/mail/em-folder-tree-model.c
@@ -640,6 +640,13 @@ folder_tree_model_dispose (GObject *object)
        }
 
        if (priv->session != NULL) {
+               MailFolderCache *folder_cache;
+
+               folder_cache = e_mail_session_get_folder_cache (priv->session);
+               g_signal_handlers_disconnect_matched (
+                       folder_cache, G_SIGNAL_MATCH_DATA,
+                       0, 0, NULL, NULL, object);
+
                g_object_unref (priv->session);
                priv->session = NULL;
        }
@@ -936,8 +943,16 @@ em_folder_tree_model_set_session (EMFolderTreeModel *model,
                g_object_ref (session);
        }
 
-       if (model->priv->session != NULL)
+       if (model->priv->session != NULL) {
+               MailFolderCache *folder_cache;
+
+               folder_cache = e_mail_session_get_folder_cache (model->priv->session);
+               g_signal_handlers_disconnect_matched (
+                       folder_cache, G_SIGNAL_MATCH_DATA,
+                       0, 0, NULL, NULL, model);
+
                g_object_unref (model->priv->session);
+       }
 
        model->priv->session = session;
 
@@ -1662,6 +1677,29 @@ em_folder_tree_model_remove_store (EMFolderTreeModel *model,
        store_info_unref (si);
 }
 
+/* This is necessary, because of circular dependency between the model
+   and its row references */
+void
+em_folder_tree_model_remove_all_stores (EMFolderTreeModel *model)
+{
+       GList *list, *link;
+
+       g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
+
+       g_mutex_lock (&model->priv->store_index_lock);
+       list = g_hash_table_get_keys (model->priv->store_index);
+       g_list_foreach (list, (GFunc) g_object_ref, NULL);
+       g_mutex_unlock (&model->priv->store_index_lock);
+
+       for (link = list; link; link = g_list_next (link)) {
+               CamelStore *store = link->data;
+
+               em_folder_tree_model_remove_store (model, store);
+       }
+
+       g_list_free_full (list, g_object_unref);
+}
+
 GList *
 em_folder_tree_model_list_stores (EMFolderTreeModel *model)
 {
diff --git a/mail/em-folder-tree-model.h b/mail/em-folder-tree-model.h
index 60c884a..325e3a5 100644
--- a/mail/em-folder-tree-model.h
+++ b/mail/em-folder-tree-model.h
@@ -125,6 +125,8 @@ void                em_folder_tree_model_add_store
 void           em_folder_tree_model_remove_store
                                        (EMFolderTreeModel *model,
                                         CamelStore *store);
+void           em_folder_tree_model_remove_all_stores
+                                       (EMFolderTreeModel *model);
 GList *                em_folder_tree_model_list_stores
                                        (EMFolderTreeModel *model);
 gboolean       em_folder_tree_model_is_type_inbox


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