[evolution-data-server] Bug 640054 - CamelDB: do not read the db while a trasaction is in progress. Fix the dead-lock cause
- From: Chenthill Palanisamy <pchen src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug 640054 - CamelDB: do not read the db while a trasaction is in progress. Fix the dead-lock cause
- Date: Thu, 26 May 2011 10:33:22 +0000 (UTC)
commit c5348d470881ed5da94462f23e354c70c5b2f4cb
Author: Chenthill Palanisamy <pchenthill novell com>
Date: Thu May 26 15:56:07 2011 +0530
Bug 640054 - CamelDB: do not read the db while a trasaction is in progress.
Fix the dead-lock caused due to transaction (DB WRITE_LOCK) and summary lock.
camel/camel-db.c | 33 ++++++++++++++++++++++++++++-----
camel/camel-folder-summary.c | 27 +++++++++++++--------------
2 files changed, 41 insertions(+), 19 deletions(-)
---
diff --git a/camel/camel-db.c b/camel/camel-db.c
index 35edacb..968cc27 100644
--- a/camel/camel-db.c
+++ b/camel/camel-db.c
@@ -1573,21 +1573,44 @@ camel_db_prepare_message_info_table (CamelDB *cdb,
GError **error)
{
gint ret, current_version;
+ GError *err = NULL;
/* Make sure we have the table already */
- ret = camel_db_create_message_info_table (cdb, folder_name, error);
+ camel_db_begin_transaction (cdb, &err);
+ ret = camel_db_create_message_info_table (cdb, folder_name, &err);
+ if (err)
+ goto exit;
+
+ camel_db_end_transaction (cdb, &err);
/* Migration stage zero: version fetch */
- current_version = camel_db_get_folder_version (cdb, folder_name, error);
+ current_version = camel_db_get_folder_version (cdb, folder_name, &err);
+ camel_db_begin_transaction (cdb, &err);
+
/* Migration stage one: storing the old data if necessary */
- ret = camel_db_migrate_folder_prepare (cdb, folder_name, current_version, error);
+ ret = camel_db_migrate_folder_prepare (cdb, folder_name, current_version, &err);
+ if (err)
+ goto exit;
/* Migration stage two: rewriting the old data if necessary */
- ret = camel_db_migrate_folder_recreate (cdb, folder_name, current_version, error);
+ ret = camel_db_migrate_folder_recreate (cdb, folder_name, current_version, &err);
+ if (err)
+ goto exit;
/* Final step: (over)write the current version label */
- ret = camel_db_write_folder_version (cdb, folder_name, current_version, error);
+ ret = camel_db_write_folder_version (cdb, folder_name, current_version, &err);
+ if (err)
+ goto exit;
+
+ camel_db_end_transaction (cdb, &err);
+
+exit:
+ if (err && cdb->priv->transaction_is_on)
+ camel_db_abort_transaction (cdb, NULL);
+
+ if (err)
+ g_propagate_error (error, err);
return ret;
}
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index 6b701ce..563dcd9 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -2146,11 +2146,15 @@ save_message_infos_to_db (CamelFolderSummary *s,
return -1;
camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
/* Push MessageInfo-es */
+ camel_db_begin_transaction (cdb, NULL);
g_hash_table_foreach (s->loaded_infos, save_to_db_cb, &args);
+ camel_db_end_transaction (cdb, NULL);
+
camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-/* FIXME[disk-summary] make sure we free the message infos that are loaded
- * are freed if not used anymore or should we leave that to the timer? */
+ /* FIXME[disk-summary] make sure we free the message infos that are loaded
+ * are freed if not used anymore or should we leave that to the timer? */
return 0;
}
@@ -2190,12 +2194,14 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s,
d(printf ("\ncamel_folder_summary_save_to_db called \n"));
if (s->priv->need_preview && g_hash_table_size (s->priv->preview_updates)) {
- camel_db_begin_transaction (parent_store->cdb_w, NULL);
camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+ camel_db_begin_transaction (parent_store->cdb_w, NULL);
g_hash_table_foreach (s->priv->preview_updates, (GHFunc) msg_save_preview, s->folder);
g_hash_table_remove_all (s->priv->preview_updates);
- camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
camel_db_end_transaction (parent_store->cdb_w, NULL);
+
+ camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
}
s->flags &= ~CAMEL_SUMMARY_DIRTY;
@@ -2204,11 +2210,8 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s,
if (!count)
return camel_folder_summary_header_save_to_db (s, error);
- camel_db_begin_transaction (cdb, NULL);
-
ret = save_message_infos_to_db (s, FALSE, error);
if (ret != 0) {
- camel_db_abort_transaction (cdb, NULL);
/* Failed, so lets reset the flag */
s->flags |= CAMEL_SUMMARY_DIRTY;
return -1;
@@ -2220,25 +2223,21 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s,
strstr ((*error)->message, "26 columns but 28 values") != NULL) {
const gchar *full_name;
- /* This is an error is previous migration. Let remigrate this folder alone. */
- camel_db_abort_transaction (cdb, NULL);
full_name = camel_folder_get_full_name (s->folder);
- camel_db_reset_folder_version (cdb, full_name, 0, NULL);
g_warning ("Fixing up a broken summary migration on %s\n", full_name);
+
/* Begin everything again. */
camel_db_begin_transaction (cdb, NULL);
+ camel_db_reset_folder_version (cdb, full_name, 0, NULL);
+ camel_db_end_transaction (cdb, NULL);
ret = save_message_infos_to_db (s, FALSE, error);
if (ret != 0) {
- camel_db_abort_transaction (cdb, NULL);
- /* Failed, so lets reset the flag */
s->flags |= CAMEL_SUMMARY_DIRTY;
return -1;
}
}
- camel_db_end_transaction (cdb, NULL);
-
record = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->summary_header_to_db (s, error);
if (!record) {
s->flags |= CAMEL_SUMMARY_DIRTY;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]