[evolution-data-server] Avoid possible deadlock with CamelStoreSummary locks
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Avoid possible deadlock with CamelStoreSummary locks
- Date: Tue, 18 Oct 2011 18:16:30 +0000 (UTC)
commit 994a77156da4eead849887e7699c8bcff580c8ba
Author: Milan Crha <mcrha redhat com>
Date: Tue Oct 18 20:12:29 2011 +0200
Avoid possible deadlock with CamelStoreSummary locks
Recently added store_summary_sync_folder_summary_count_cb() could
cause deadlock when locking SUMMARY_LOCK first, and then calling
functions which lock REF_LOCK before SUMMARY_LOCK. Locking REF_LOCK
first avoids this.
camel/camel-store-summary.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
---
diff --git a/camel/camel-store-summary.c b/camel/camel-store-summary.c
index 96d9132..1b3c7e8 100644
--- a/camel/camel-store-summary.c
+++ b/camel/camel-store-summary.c
@@ -1115,10 +1115,12 @@ store_summary_sync_folder_summary_count_cb (CamelFolderSummary *folder_summary,
path = g_hash_table_lookup (summary->priv->folder_summaries, folder_summary);
g_return_if_fail (path != NULL);
+ camel_store_summary_lock (summary, CAMEL_STORE_SUMMARY_REF_LOCK);
camel_store_summary_lock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
si = camel_store_summary_path (summary, path);
if (!si) {
camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+ camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_REF_LOCK);
g_warning ("%s: Store summary %p doesn't hold path '%s'", G_STRFUNC, summary, path);
return;
}
@@ -1136,6 +1138,7 @@ store_summary_sync_folder_summary_count_cb (CamelFolderSummary *folder_summary,
camel_store_summary_info_free (summary, si);
camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+ camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_REF_LOCK);
}
/**
@@ -1167,11 +1170,13 @@ camel_store_summary_connect_folder_summary (CamelStoreSummary *summary,
g_return_val_if_fail (path != NULL, FALSE);
g_return_val_if_fail (folder_summary != NULL, FALSE);
+ camel_store_summary_lock (summary, CAMEL_STORE_SUMMARY_REF_LOCK);
camel_store_summary_lock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
si = camel_store_summary_path (summary, path);
if (!si) {
camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+ camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_REF_LOCK);
g_warning ("%s: Store summary %p doesn't hold path '%s'", G_STRFUNC, summary, path);
return FALSE;
}
@@ -1180,6 +1185,7 @@ camel_store_summary_connect_folder_summary (CamelStoreSummary *summary,
if (g_hash_table_lookup (summary->priv->folder_summaries, folder_summary)) {
camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+ camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_REF_LOCK);
g_warning ("%s: Store summary %p already listens on folder summary %p", G_STRFUNC, summary, folder_summary);
return FALSE;
}
@@ -1189,6 +1195,7 @@ camel_store_summary_connect_folder_summary (CamelStoreSummary *summary,
g_signal_connect (folder_summary, "notify::unread-count", G_CALLBACK (store_summary_sync_folder_summary_count_cb), summary);
camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+ camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_REF_LOCK);
return TRUE;
}
@@ -1214,10 +1221,12 @@ camel_store_summary_disconnect_folder_summary (CamelStoreSummary *summary,
g_return_val_if_fail (summary->priv != NULL, FALSE);
g_return_val_if_fail (folder_summary != NULL, FALSE);
+ camel_store_summary_lock (summary, CAMEL_STORE_SUMMARY_REF_LOCK);
camel_store_summary_lock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
if (!g_hash_table_lookup (summary->priv->folder_summaries, folder_summary)) {
camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+ camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_REF_LOCK);
g_warning ("%s: Store summary %p is not connected to folder summary %p", G_STRFUNC, summary, folder_summary);
return FALSE;
}
@@ -1226,6 +1235,7 @@ camel_store_summary_disconnect_folder_summary (CamelStoreSummary *summary,
g_hash_table_remove (summary->priv->folder_summaries, folder_summary);
camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+ camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_REF_LOCK);
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]