diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2010-10-01 05:29:06 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2010-10-01 05:44:53 +0800 |
commit | dad7910a1b8a01e4401339fda39309c157a89145 (patch) | |
tree | 864ca18dd8d09174397451f566b9bbcc6a42b910 /mail | |
parent | 1a6782bfc18d2b2d6eb5e57194f0d3a086cfabce (diff) | |
download | gsoc2013-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')
-rw-r--r-- | 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 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); } /** |