[PATCH 08/17] lib: Add support for nested atomic sections.

Austin Clements amdragon at MIT.EDU
Sat Jun 11 13:04:34 PDT 2011


notmuch_database_t now keeps a nesting count and we only start a
transaction or commit for the outermost atomic section.

Introduces a new error, NOTMUCH_STATUS_UNBALANCED_ATOMIC.
---
 lib/database-private.h |    1 +
 lib/database.cc        |   22 ++++++++++++++++++----
 lib/notmuch.h          |   10 ++++++++++
 notmuch-new.c          |    1 +
 4 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/lib/database-private.h b/lib/database-private.h
index f705009..88532d5 100644
--- a/lib/database-private.h
+++ b/lib/database-private.h
@@ -43,6 +43,7 @@ struct _notmuch_database {
 
     notmuch_bool_t needs_upgrade;
     notmuch_database_mode_t mode;
+    int atomic_nesting;
     Xapian::Database *xapian_db;
 
     unsigned int last_doc_id;
diff --git a/lib/database.cc b/lib/database.cc
index ddb6167..b766e94 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -273,6 +273,8 @@ notmuch_status_to_string (notmuch_status_t status)
 	return "Tag value is too long (exceeds NOTMUCH_TAG_MAX)";
     case NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW:
 	return "Unbalanced number of calls to notmuch_message_freeze/thaw";
+    case NOTMUCH_STATUS_UNBALANCED_ATOMIC:
+	return "Unbalanced number of calls to notmuch_database_begin_atomic/end_atomic";
     default:
     case NOTMUCH_STATUS_LAST_STATUS:
 	return "Unknown error status value";
@@ -611,6 +613,7 @@ notmuch_database_open (const char *path,
 
     notmuch->needs_upgrade = FALSE;
     notmuch->mode = mode;
+    notmuch->atomic_nesting = 0;
     try {
 	string last_thread_id;
 
@@ -977,8 +980,9 @@ notmuch_database_upgrade (notmuch_database_t *notmuch,
 notmuch_status_t
 notmuch_database_begin_atomic (notmuch_database_t *notmuch)
 {
-    if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY)
-	return NOTMUCH_STATUS_SUCCESS;
+    if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY ||
+	notmuch->atomic_nesting > 0)
+	goto DONE;
 
     try {
 	(static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db))->begin_transaction (false);
@@ -988,6 +992,9 @@ notmuch_database_begin_atomic (notmuch_database_t *notmuch)
 	notmuch->exception_reported = TRUE;
 	return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
     }
+
+DONE:
+    notmuch->atomic_nesting++;
     return NOTMUCH_STATUS_SUCCESS;
 }
 
@@ -996,8 +1003,12 @@ notmuch_database_end_atomic (notmuch_database_t *notmuch)
 {
     Xapian::WritableDatabase *db;
 
-    if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY)
-	return NOTMUCH_STATUS_SUCCESS;
+    if (notmuch->atomic_nesting == 0)
+	return NOTMUCH_STATUS_UNBALANCED_ATOMIC;
+
+    if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY ||
+	notmuch->atomic_nesting > 1)
+	goto DONE;
 
     db = static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db);
     try {
@@ -1015,6 +1026,9 @@ notmuch_database_end_atomic (notmuch_database_t *notmuch)
 	notmuch->exception_reported = TRUE;
 	return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
     }
+
+DONE:
+    notmuch->atomic_nesting--;
     return NOTMUCH_STATUS_SUCCESS;
 }
 
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 208d22c..830aa41 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -81,6 +81,9 @@ typedef int notmuch_bool_t;
  * NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW: The notmuch_message_thaw
  *	function has been called more times than notmuch_message_freeze.
  *
+ * NOTMUCH_STATUS_UNBALANCED_ATOMIC: notmuch_database_end_atomic has
+ *	been called more times than notmuch_database_begin_atomic.
+ *
  * And finally:
  *
  * NOTMUCH_STATUS_LAST_STATUS: Not an actual status value. Just a way
@@ -97,6 +100,7 @@ typedef enum _notmuch_status {
     NOTMUCH_STATUS_NULL_POINTER,
     NOTMUCH_STATUS_TAG_TOO_LONG,
     NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW,
+    NOTMUCH_STATUS_UNBALANCED_ATOMIC,
 
     NOTMUCH_STATUS_LAST_STATUS
 } notmuch_status_t;
@@ -222,6 +226,9 @@ notmuch_database_upgrade (notmuch_database_t *database,
  * only ensures atomicity, not durability; neither begin nor end
  * necessarily flush modifications to disk.
  *
+ * Atomic sections may be nested.  begin_atomic and end_atomic must
+ * always be called in pairs.
+ *
  * Return value:
  *
  * NOTMUCH_STATUS_SUCCESS: Successfully entered atomic section.
@@ -240,6 +247,9 @@ notmuch_database_begin_atomic (notmuch_database_t *notmuch);
  *
  * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred;
  *	atomic section not ended.
+ *
+ * NOTMUCH_STATUS_UNBALANCED_ATOMIC: The database is not currently in
+ *	an atomic section.
  */
 notmuch_status_t
 notmuch_database_end_atomic (notmuch_database_t *notmuch);
diff --git a/notmuch-new.c b/notmuch-new.c
index b76b608..d1bea55 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -466,6 +466,7 @@ add_files_recursive (notmuch_database_t *notmuch,
 	case NOTMUCH_STATUS_NULL_POINTER:
 	case NOTMUCH_STATUS_TAG_TOO_LONG:
 	case NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW:
+	case NOTMUCH_STATUS_UNBALANCED_ATOMIC:
 	case NOTMUCH_STATUS_LAST_STATUS:
 	    INTERNAL_ERROR ("add_message returned unexpected value: %d",  status);
 	    goto DONE;
-- 
1.7.5.1



More information about the notmuch mailing list