From 50ce9f5828ca14e22a54e2f56b240b2fcd25a682 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Thu, 26 Nov 2015 15:16:26 +0100 Subject: [POP3] Avoid deadlock around pop3_folder_get_message_sync() The function could be called from within camel_pop3_folder_delete_old(), which already holds the lock, thus the later attempt leads to a deadlock. Reported by cooly. --- camel/providers/pop3/camel-pop3-folder.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/camel/providers/pop3/camel-pop3-folder.c b/camel/providers/pop3/camel-pop3-folder.c index f0f4b76c2..e41584faa 100644 --- a/camel/providers/pop3/camel-pop3-folder.c +++ b/camel/providers/pop3/camel-pop3-folder.c @@ -395,10 +395,11 @@ pop3_folder_set_message_flags (CamelFolder *folder, } static CamelMimeMessage * -pop3_folder_get_message_sync (CamelFolder *folder, - const gchar *uid, - GCancellable *cancellable, - GError **error) +pop3_folder_get_message_internal_sync (CamelFolder *folder, + const gchar *uid, + gboolean already_locked, + GCancellable *cancellable, + GError **error) { CamelStore *parent_store; CamelMimeMessage *message = NULL; @@ -457,7 +458,7 @@ pop3_folder_get_message_sync (CamelFolder *folder, pop3_engine = camel_pop3_store_ref_engine (pop3_store); - if (!camel_pop3_engine_busy_lock (pop3_engine, cancellable, error)) + if (!already_locked && !camel_pop3_engine_busy_lock (pop3_engine, cancellable, error)) goto fail; /* If we have an oustanding retrieve message running, wait for that to complete @@ -475,7 +476,8 @@ pop3_folder_get_message_sync (CamelFolder *folder, if (i == -1) { g_prefix_error ( error, _("Cannot get message %s: "), uid); - camel_pop3_engine_busy_unlock (pop3_engine); + if (!already_locked) + camel_pop3_engine_busy_unlock (pop3_engine); goto fail; } } @@ -586,7 +588,8 @@ pop3_folder_get_message_sync (CamelFolder *folder, camel_medium_add_header (CAMEL_MEDIUM (message), "X-Evolution-POP3-UID", uid); } done: - camel_pop3_engine_busy_unlock (pop3_engine); + if (!already_locked) + camel_pop3_engine_busy_unlock (pop3_engine); g_clear_object (&stream); fail: g_clear_object (&pop3_engine); @@ -596,6 +599,15 @@ fail: return message; } +static CamelMimeMessage * +pop3_folder_get_message_sync (CamelFolder *folder, + const gchar *uid, + GCancellable *cancellable, + GError **error) +{ + return pop3_folder_get_message_internal_sync (folder, uid, FALSE, cancellable, error); +} + static gboolean pop3_folder_refresh_info_sync (CamelFolder *folder, GCancellable *cancellable, @@ -1079,8 +1091,8 @@ camel_pop3_folder_delete_old (CamelFolder *folder, d (printf ("%s(%d): fi->uid=[%s]\n", __FILE__, __LINE__, fi->uid)); if (!pop3_get_message_time_from_cache (folder, fi->uid, &message_time)) { d (printf ("could not get message time from cache, trying from pop3\n")); - message = pop3_folder_get_message_sync ( - folder, fi->uid, cancellable, error); + message = pop3_folder_get_message_internal_sync ( + folder, fi->uid, TRUE, cancellable, error); if (message) { message_time = message->date + message->date_offset; g_object_unref (message); -- cgit v1.2.1