[evolution-data-server/evolution-data-server-3-12] camel_imapx_conn_manager_close_connections: Avoid possible deadlock



commit 715ccafb6ba8efe7c1e2a2688aededfb74af415c
Author: Milan Crha <mcrha redhat com>
Date:   Mon May 5 17:49:13 2014 +0200

    camel_imapx_conn_manager_close_connections: Avoid possible deadlock
    
    A deadlock could happen by calling CamelIMAPXServer functions with
    the CamelIMAPXConnManager write lock locked, where there was a race
    condition between the write lock and the server's queue lock. Closing
    all the connections without holding the write lock should avoid
    the deadlock.

 camel/providers/imapx/camel-imapx-conn-manager.c |   17 ++++++++---------
 1 files changed, 8 insertions(+), 9 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-conn-manager.c 
b/camel/providers/imapx/camel-imapx-conn-manager.c
index 75942dd..dce259c 100644
--- a/camel/providers/imapx/camel-imapx-conn-manager.c
+++ b/camel/providers/imapx/camel-imapx-conn-manager.c
@@ -879,7 +879,7 @@ void
 camel_imapx_conn_manager_close_connections (CamelIMAPXConnManager *con_man,
                                            const GError *error)
 {
-       GList *iter;
+       GList *iter, *connections;
 
        g_return_if_fail (CAMEL_IS_IMAPX_CONN_MANAGER (con_man));
 
@@ -887,15 +887,14 @@ camel_imapx_conn_manager_close_connections (CamelIMAPXConnManager *con_man,
 
        c('*', "Closing all %d connections, with propagated error: %s\n", g_list_length 
(con_man->priv->connections), error ? error->message : "none");
 
-       for (iter = con_man->priv->connections; iter; iter = g_list_next (iter)) {
-               connection_info_set_shutdown_error (iter->data, error);
-       }
-
-       g_list_free_full (
-               con_man->priv->connections,
-               (GDestroyNotify) connection_info_cancel_and_unref);
+       connections = con_man->priv->connections;
        con_man->priv->connections = NULL;
 
        CON_WRITE_UNLOCK (con_man);
-}
 
+       for (iter = connections; iter; iter = g_list_next (iter)) {
+               connection_info_set_shutdown_error (iter->data, error);
+       }
+
+       g_list_free_full (connections, (GDestroyNotify) connection_info_cancel_and_unref);
+}


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