From 3acdc755d63edcc65ef58adefbced984d37e7c50 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Sun, 19 Oct 2008 17:08:50 +0000 Subject: ** Fix for bug #438155 2008-10-19 Milan Crha ** Fix for bug #438155 * message-list.h: (struct _MessageList): message-list.c: (message_list_init), (message_list_finalise), (regen_list_done), (regen_list_free), (ml_regen_timeout), (mail_regen_cancel): Guard access to the 'regen' list with a lock. svn path=/trunk/; revision=36652 --- mail/ChangeLog | 9 +++++++++ mail/message-list.c | 16 +++++++++++++++- mail/message-list.h | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) (limited to 'mail') diff --git a/mail/ChangeLog b/mail/ChangeLog index 4c7c9fde3b..14de3d2e5a 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,12 @@ +2008-10-19 Milan Crha + + ** Fix for bug #438155 + + * message-list.h: (struct _MessageList): + * message-list.c: (message_list_init), (message_list_finalise), + (regen_list_done), (regen_list_free), (ml_regen_timeout), + (mail_regen_cancel): Guard access to the 'regen' list with a lock. + 2008-10-17 Srinivasa Ragavan ** Fix for bug #555276 diff --git a/mail/message-list.c b/mail/message-list.c index d8d92af49d..7333467fd1 100644 --- a/mail/message-list.c +++ b/mail/message-list.c @@ -2274,6 +2274,8 @@ message_list_init (MessageList *message_list) message_list->cursor_uid = NULL; message_list->last_sel_single = FALSE; + message_list->regen_lock = g_mutex_new (); + /* TODO: Should this only get the selection if we're realised? */ p = message_list->priv = g_malloc0(sizeof(*message_list->priv)); p->invisible = gtk_invisible_new(); @@ -2375,6 +2377,7 @@ message_list_finalise (GObject *object) g_free(message_list->cursor_uid); g_mutex_free(message_list->hide_lock); + g_mutex_free (message_list->regen_lock); g_free(message_list->folder_uri); message_list->folder_uri = NULL; @@ -4256,7 +4259,9 @@ regen_list_done (struct _regen_list_msg *m) m->ml->search = m->search; m->search = NULL; + g_mutex_lock (m->ml->regen_lock); m->ml->regen = g_list_remove(m->ml->regen, m); + g_mutex_unlock (m->ml->regen_lock); if (m->ml->regen == NULL && m->ml->pending_select_uid) { char *uid = m->ml->pending_select_uid; @@ -4319,7 +4324,9 @@ regen_list_free (struct _regen_list_msg *m) camel_folder_change_info_free (m->changes); /* we have to poke this here as well since we might've been cancelled and regened wont get called */ + g_mutex_lock (m->ml->regen_lock); m->ml->regen = g_list_remove(m->ml->regen, m); + g_mutex_unlock (m->ml->regen_lock); if (m->expand_state) xmlFreeDoc (m->expand_state); @@ -4340,7 +4347,9 @@ ml_regen_timeout(struct _regen_list_msg *m) { e_profile_event_emit("list.regenerate", m->folder->full_name, 0); + g_mutex_lock (m->ml->regen_lock); m->ml->regen = g_list_prepend(m->ml->regen, m); + g_mutex_unlock (m->ml->regen_lock); /* TODO: we should manage our own thread stuff, would make cancelling outstanding stuff easier */ mail_msg_fast_ordered_push (m); @@ -4355,8 +4364,11 @@ mail_regen_cancel(MessageList *ml) { /* cancel any outstanding regeneration requests, not we don't clear, they clear themselves */ if (ml->regen) { - GList *l = ml->regen; + GList *l; + + g_mutex_lock (ml->regen_lock); + l = ml->regen; while (l) { MailMsg *mm = l->data; @@ -4364,6 +4376,8 @@ mail_regen_cancel(MessageList *ml) camel_operation_cancel(mm->cancel); l = l->next; } + + g_mutex_unlock (ml->regen_lock); } /* including unqueued ones */ diff --git a/mail/message-list.h b/mail/message-list.h index cc58e1e798..47be897fd2 100644 --- a/mail/message-list.h +++ b/mail/message-list.h @@ -151,6 +151,7 @@ struct _MessageList { /* list of outstanding regeneration requests */ GList *regen; + GMutex *regen_lock; /* when writing to the regen, guard with this lock too */ char *pending_select_uid; /* set if we were busy regnerating while we had a select come in */ guint regen_timeout_id; void *regen_timeout_msg; -- cgit