lib: Wrap notmuch_database_add_message in an atomic section.
authorAustin Clements <amdragon@mit.edu>
Sat, 11 Jun 2011 04:42:58 +0000 (00:42 -0400)
committerDavid Bremner <bremner@debian.org>
Sat, 24 Sep 2011 23:00:28 +0000 (20:00 -0300)
Adding a message may involve changes to multiple database documents,
and thus needs to be done in a transaction.  This makes add_message
(and, I think, the whole library) atomicity-safe: library callers only
needs to use atomic sections if they needs atomicity across multiple
library calls.

lib/database.cc

index f8b95bc46f5fcacf61839c30b4b1cf17a124c9f4..9299c8d52e3c3e0a93c6906a64956236175abb60 100644 (file)
@@ -1601,7 +1601,7 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
 {
     notmuch_message_file_t *message_file;
     notmuch_message_t *message = NULL;
 {
     notmuch_message_file_t *message_file;
     notmuch_message_t *message = NULL;
-    notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
+    notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS, ret2;
     notmuch_private_status_t private_status;
 
     const char *date, *header;
     notmuch_private_status_t private_status;
 
     const char *date, *header;
@@ -1619,6 +1619,12 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
     if (message_file == NULL)
        return NOTMUCH_STATUS_FILE_ERROR;
 
     if (message_file == NULL)
        return NOTMUCH_STATUS_FILE_ERROR;
 
+    /* Adding a message may change many documents.  Do this all
+     * atomically. */
+    ret = notmuch_database_begin_atomic (notmuch);
+    if (ret)
+       goto DONE;
+
     notmuch_message_file_restrict_headers (message_file,
                                           "date",
                                           "from",
     notmuch_message_file_restrict_headers (message_file,
                                           "date",
                                           "from",
@@ -1740,6 +1746,12 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
     if (message_file)
        notmuch_message_file_close (message_file);
 
     if (message_file)
        notmuch_message_file_close (message_file);
 
+    ret2 = notmuch_database_end_atomic (notmuch);
+    if ((ret == NOTMUCH_STATUS_SUCCESS ||
+        ret == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) &&
+       ret2 != NOTMUCH_STATUS_SUCCESS)
+       ret = ret2;
+
     return ret;
 }
 
     return ret;
 }