[evolution-data-server] [IMAPx] Possible deadlock in camel_imapx_server_stop_idle_sync()



commit 8bbffdb0dda405d782e200f1a093d835157f4332
Author: Milan Crha <mcrha redhat com>
Date:   Thu Jul 7 17:08:07 2016 +0200

    [IMAPx] Possible deadlock in camel_imapx_server_stop_idle_sync()
    
    As reported in bug #748223, when the cancellable is already cancelled,
    the imapx_server_wait_idle_stop_cancelled_cb() is called immediately,
    which means the idle_lock is tried to be locked when the same thread
    already holds it, which leads to the deadlock.

 camel/providers/imapx/camel-imapx-server.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index c58325c..be72c01 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -6358,9 +6358,16 @@ camel_imapx_server_stop_idle_sync (CamelIMAPXServer *is,
        g_clear_object (&is->priv->idle_mailbox);
        is->priv->idle_stamp++;
 
-       if (cancellable)
+       if (cancellable) {
+               g_mutex_unlock (&is->priv->idle_lock);
+
+               /* Do not hold the idle_lock here, because the callback can be called
+                  immediately, which leads to a deadlock inside it. */
                handler_id = g_cancellable_connect (cancellable, G_CALLBACK 
(imapx_server_wait_idle_stop_cancelled_cb), is, NULL);
 
+               g_mutex_lock (&is->priv->idle_lock);
+       }
+
        while (is->priv->idle_state == IMAPX_IDLE_STATE_PREPARING &&
               !g_cancellable_is_cancelled (cancellable)) {
                g_cond_wait (&is->priv->idle_cond, &is->priv->idle_lock);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]