[evolution-data-server/evolution-data-server-3-12] camel_imapx_conn_manager_close_connections: Avoid possible deadlock
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/evolution-data-server-3-12] camel_imapx_conn_manager_close_connections: Avoid possible deadlock
- Date: Mon, 5 May 2014 15:53:19 +0000 (UTC)
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]