[evolution] Fix some CamelFolderChangeInfo lifecycle issues.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] Fix some CamelFolderChangeInfo lifecycle issues.
- Date: Thu, 30 Sep 2010 21:45:10 +0000 (UTC)
commit dad7910a1b8a01e4401339fda39309c157a89145
Author: Matthew Barnes <mbarnes redhat com>
Date: Thu Sep 30 17:29:06 2010 -0400
Fix some CamelFolderChangeInfo lifecycle issues.
Apparently MessageList eats the CamelFolderChangeInfo it gets from the
CamelFolder::changed signal. My confidence in this patch is shaky. The
logic is pretty messy and we could easily be leaking memory here. Could
use some hot valgrind action.
mail/message-list.c | 65 +++++++++++++++++++++++++++++++++-----------------
1 files changed, 43 insertions(+), 22 deletions(-)
---
diff --git a/mail/message-list.c b/mail/message-list.c
index eef110e..ab4778a 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -3583,43 +3583,55 @@ build_flat_diff (MessageList *ml, CamelFolderChangeInfo *changes)
}
#endif /* BROKEN_ETREE */
-static void
-mail_folder_hide_by_flag (CamelFolder *folder, MessageList *ml, CamelFolderChangeInfo **changes, gint flag)
+static CamelFolderChangeInfo *
+mail_folder_hide_by_flag (CamelFolder *folder,
+ MessageList *ml,
+ CamelFolderChangeInfo *changes,
+ gint flag)
{
- CamelFolderChangeInfo *newchanges, *oldchanges = *changes;
+ CamelFolderChangeInfo *newchanges;
CamelMessageInfo *info;
gint i;
newchanges = camel_folder_change_info_new ();
- for (i = 0; i < oldchanges->uid_changed->len; i++) {
- ETreePath node = g_hash_table_lookup (ml->uid_nodemap, oldchanges->uid_changed->pdata[i]);
+ for (i = 0; i < changes->uid_changed->len; i++) {
+ ETreePath node;
guint32 flags;
- info = camel_folder_get_message_info (folder, oldchanges->uid_changed->pdata[i]);
+ node = g_hash_table_lookup (
+ ml->uid_nodemap, changes->uid_changed->pdata[i]);
+ info = camel_folder_get_message_info (
+ folder, changes->uid_changed->pdata[i]);
if (info)
flags = camel_message_info_flags (info);
if (node != NULL && info != NULL && (flags & flag) != 0)
- camel_folder_change_info_remove_uid (newchanges, oldchanges->uid_changed->pdata[i]);
+ camel_folder_change_info_remove_uid (
+ newchanges, changes->uid_changed->pdata[i]);
else if (node == NULL && info != NULL && (flags & flag) == 0)
- camel_folder_change_info_add_uid (newchanges, oldchanges->uid_changed->pdata[i]);
+ camel_folder_change_info_add_uid (
+ newchanges, changes->uid_changed->pdata[i]);
else
- camel_folder_change_info_change_uid (newchanges, oldchanges->uid_changed->pdata[i]);
+ camel_folder_change_info_change_uid (
+ newchanges, changes->uid_changed->pdata[i]);
if (info)
camel_folder_free_message_info (folder, info);
}
if (newchanges->uid_added->len > 0 || newchanges->uid_removed->len > 0) {
- for (i = 0; i < oldchanges->uid_added->len; i++)
- camel_folder_change_info_add_uid (newchanges, oldchanges->uid_added->pdata[i]);
- for (i = 0; i < oldchanges->uid_removed->len; i++)
- camel_folder_change_info_remove_uid (newchanges, oldchanges->uid_removed->pdata[i]);
- camel_folder_change_info_free (oldchanges);
- *changes = newchanges;
+ for (i = 0; i < changes->uid_added->len; i++)
+ camel_folder_change_info_add_uid (
+ newchanges, changes->uid_added->pdata[i]);
+ for (i = 0; i < changes->uid_removed->len; i++)
+ camel_folder_change_info_remove_uid (
+ newchanges, changes->uid_removed->pdata[i]);
} else {
- camel_folder_change_info_free (newchanges);
+ camel_folder_change_info_clear (newchanges);
+ camel_folder_change_info_cat (newchanges, changes);
}
+
+ return newchanges;
}
static void
@@ -3627,6 +3639,7 @@ folder_changed (CamelFolder *folder,
CamelFolderChangeInfo *changes,
MessageList *ml)
{
+ CamelFolderChangeInfo *altered_changes = NULL;
gint i;
if (ml->priv->destroyed)
@@ -3644,11 +3657,18 @@ folder_changed (CamelFolder *folder,
/* check if the hidden state has changed, if so modify accordingly, then regenerate */
if (ml->hidejunk || ml->hidedeleted)
- mail_folder_hide_by_flag (folder, ml, &changes, (ml->hidejunk ? CAMEL_MESSAGE_JUNK : 0) | (ml->hidedeleted ? CAMEL_MESSAGE_DELETED : 0));
+ altered_changes = mail_folder_hide_by_flag (
+ folder, ml, changes,
+ (ml->hidejunk ? CAMEL_MESSAGE_JUNK : 0) |
+ (ml->hidedeleted ? CAMEL_MESSAGE_DELETED : 0));
+ else {
+ altered_changes = camel_folder_change_info_new ();
+ camel_folder_change_info_cat (altered_changes, changes);
+ }
- if (changes->uid_added->len == 0 && changes->uid_removed->len == 0 && changes->uid_changed->len < 100) {
- for (i = 0; i < changes->uid_changed->len; i++) {
- ETreePath node = g_hash_table_lookup (ml->uid_nodemap, changes->uid_changed->pdata[i]);
+ if (altered_changes->uid_added->len == 0 && altered_changes->uid_removed->len == 0 && altered_changes->uid_changed->len < 100) {
+ for (i = 0; i < altered_changes->uid_changed->len; i++) {
+ ETreePath node = g_hash_table_lookup (ml->uid_nodemap, altered_changes->uid_changed->pdata[i]);
if (node) {
e_tree_model_pre_change (ml->model);
e_tree_model_node_data_changed (ml->model, node);
@@ -3657,14 +3677,15 @@ folder_changed (CamelFolder *folder,
}
}
- camel_folder_change_info_free (changes);
+ camel_folder_change_info_free (altered_changes);
g_signal_emit (ml, message_list_signals[MESSAGE_LIST_BUILT], 0);
return;
}
}
- mail_regen_list (ml, ml->search, NULL, changes);
+ /* XXX This apparently eats the ChangeFolderChangeInfo. */
+ mail_regen_list (ml, ml->search, NULL, altered_changes);
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]