aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--lib/database-private.h1
-rw-r--r--lib/database.cc22
-rw-r--r--lib/notmuch.h10
-rw-r--r--notmuch-new.c1
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 <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 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;