From e59cc0031fbf84f49e32dedb9927f427d2c49309 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Fri, 10 Jun 2011 23:35:06 -0400 Subject: [PATCH 1/1] lib: Add support for nested atomic sections. 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 f7050097..88532d51 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 48abbe8e..92c3c4e0 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 (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 (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 0c306bb5..bfa2ced8 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 fb59d90c..82e2d358 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -488,6 +488,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; -- 2.43.0