[evolution] Bug 704663 - Crash under em_folder_tree_model_add_store()



commit 6576094f7e7ee1910c1e57d689dc38abe2813e6e
Author: Milan Crha <mcrha redhat com>
Date:   Wed Jun 11 12:26:13 2014 +0200

    Bug 704663 - Crash under em_folder_tree_model_add_store()

 mail/e-mail-folder-create-dialog.c |    8 ++++--
 mail/em-folder-selector.c          |    3 ++
 mail/em-folder-tree-model.c        |   40 +++++++++++++++++++++++++++++++++++-
 mail/em-folder-tree-model.h        |    2 +
 4 files changed, 49 insertions(+), 4 deletions(-)
---
diff --git a/mail/e-mail-folder-create-dialog.c b/mail/e-mail-folder-create-dialog.c
index bca14de..e1e9bdd 100644
--- a/mail/e-mail-folder-create-dialog.c
+++ b/mail/e-mail-folder-create-dialog.c
@@ -403,9 +403,11 @@ mail_folder_create_dialog_folder_selected (EMFolderSelector *selector,
 
        dialog = E_MAIL_FOLDER_CREATE_DIALOG (selector);
 
-       gtk_dialog_set_response_sensitive (
-               GTK_DIALOG (dialog), GTK_RESPONSE_OK,
-               mail_folder_create_dialog_inputs_are_valid (dialog));
+       /* Can be NULL during dispose, when the folder tree model is being cleared */
+       if (dialog->priv->name_entry)
+               gtk_dialog_set_response_sensitive (
+                       GTK_DIALOG (dialog), GTK_RESPONSE_OK,
+                       mail_folder_create_dialog_inputs_are_valid (dialog));
 }
 
 static void
diff --git a/mail/em-folder-selector.c b/mail/em-folder-selector.c
index e1b2127..abe0341 100644
--- a/mail/em-folder-selector.c
+++ b/mail/em-folder-selector.c
@@ -252,6 +252,9 @@ folder_selector_dispose (GObject *object)
 
        priv = EM_FOLDER_SELECTOR_GET_PRIVATE (object);
 
+       if (priv->model && priv->model != em_folder_tree_model_get_default ())
+               em_folder_tree_model_remove_all_stores (priv->model);
+
        g_clear_object (&priv->model);
        g_clear_object (&priv->alert_bar);
        g_clear_object (&priv->activity_bar);
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]