diff options
author | Milan Crha <mcrha@redhat.com> | 2015-11-26 15:16:26 +0100 |
---|---|---|
committer | Milan Crha <mcrha@redhat.com> | 2015-11-26 15:18:55 +0100 |
commit | 50ce9f5828ca14e22a54e2f56b240b2fcd25a682 (patch) | |
tree | 08cde8fabdfaba1e8563b93571a8e732e4c3a4b4 | |
parent | 41a388df9b9a69ffff7eecb0e846c7a6e2a44210 (diff) | |
download | evolution-data-server-50ce9f5828ca14e22a54e2f56b240b2fcd25a682.tar.gz |
[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.
-rw-r--r-- | camel/providers/pop3/camel-pop3-folder.c | 30 |
1 files 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); |