aboutsummaryrefslogtreecommitdiffstats
path: root/mail/message-list.c
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2010-10-01 05:29:06 +0800
committerMatthew Barnes <mbarnes@redhat.com>2010-10-01 05:44:53 +0800
commitdad7910a1b8a01e4401339fda39309c157a89145 (patch)
tree864ca18dd8d09174397451f566b9bbcc6a42b910 /mail/message-list.c
parent1a6782bfc18d2b2d6eb5e57194f0d3a086cfabce (diff)
downloadgsoc2013-evolution-dad7910a1b8a01e4401339fda39309c157a89145.tar.gz
gsoc2013-evolution-dad7910a1b8a01e4401339fda39309c157a89145.tar.zst
gsoc2013-evolution-dad7910a1b8a01e4401339fda39309c157a89145.zip
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.
Diffstat (limited to 'mail/message-list.c')
-rw-r--r--mail/message-list.c65
1 files changed, 43 insertions, 22 deletions
diff --git a/mail/message-list.c b/mail/message-list.c
index eef110e3f0..ab4778a9bd 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);
}
/**