diff options
author | Milan Crha <mcrha@redhat.com> | 2011-10-18 20:12:29 +0200 |
---|---|---|
committer | Milan Crha <mcrha@redhat.com> | 2011-10-18 20:12:29 +0200 |
commit | 994a77156da4eead849887e7699c8bcff580c8ba (patch) | |
tree | 901420203ebacf990d03a8b2cc11caa86e3981a9 | |
parent | 01f8a361389e065aa671ef17703a8d007100a881 (diff) | |
download | evolution-data-server-994a77156da4eead849887e7699c8bcff580c8ba.tar.gz |
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.
-rw-r--r-- | 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 96d913240..1b3c7e84b 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; } |