Use the Xapian::DB_RETRY_LOCK flag when available
authorIstvan Marko <notmuch@kismala.com>
Sun, 26 Jun 2016 15:29:43 +0000 (17:29 +0200)
committerDavid Bremner <david@tethera.net>
Wed, 29 Jun 2016 07:03:34 +0000 (09:03 +0200)
Xapian 1.3 has introduced the DB_RETRY_LOCK flag (Xapian bug
275). Detect it in configure and optionally use it. With this flag
commands that need the write lock will wait for their turn instead of
aborting when it's not immediately available.

Amended by db: allow disabling in configure

configure
lib/database.cc

index 49fa5b934566d0370777797ba3921243527652dc..ae0a02709e2d611197b1a9903ede242d95897183 100755 (executable)
--- a/configure
+++ b/configure
@@ -72,6 +72,7 @@ WITH_EMACS=1
 WITH_BASH=1
 WITH_RUBY=1
 WITH_ZSH=1
+WITH_RETRY_LOCK=1
 
 usage ()
 {
@@ -140,6 +141,7 @@ Some features can be disabled (--with-feature=no is equivalent to
        --without-emacs                 Do not install lisp file
        --without-ruby                  Do not install ruby bindings
        --without-zsh-completion        Do not install zsh completions files
+       --without-retry-lock            Do not use blocking xapian opens, even if available
 
 Additional options are accepted for compatibility with other
 configure-script calling conventions, but don't do anything yet:
@@ -211,6 +213,14 @@ for option; do
        fi
     elif [ "${option}" = '--without-ruby' ] ; then
        WITH_RUBY=0
+    elif [ "${option%%=*}" = '--with-retry-lock' ]; then
+       if [ "${option#*=}" = 'no' ]; then
+           WITH_RETRY_LOCK=0
+       else
+           WITH_RETRY_LOCK=1
+       fi
+    elif [ "${option}" = '--without-retry-lock' ] ; then
+       WITH_RETRY_LOCK=0
     elif [ "${option%%=*}" = '--with-zsh-completion' ]; then
        if [ "${option#*=}" = 'no' ]; then
            WITH_ZSH=0
@@ -392,6 +402,24 @@ EOF
     rm -f _field_processor.o _field_processor.cc
 
     default_xapian_backend=""
+    # DB_RETRY_LOCK is only supported on Xapian > 1.3.2
+    have_xapian_db_retry_lock=0
+    if [ $WITH_RETRY_LOCK = "1" ]; then
+       printf "Checking for Xapian lock retry support... "
+       cat>_retry.cc<<EOF
+#include <xapian.h>
+int flag = Xapian::DB_RETRY_LOCK;
+EOF
+       if ${CXX} ${CXXFLAGS_for_sh} ${xapian_cxxflags} -c _retry.cc -o _retry.o > /dev/null 2>&1
+       then
+           have_xapian_db_retry_lock=1
+           printf "Yes.\n"
+       else
+           printf "No. (optional)\n"
+       fi
+       rm -f _retry.o _retry.cc
+    fi
+
     printf "Testing default Xapian backend... "
     cat >_default_backend.cc <<EOF
 #include <xapian.h>
@@ -1022,6 +1050,9 @@ HAVE_XAPIAN_COMPACT = ${have_xapian_compact}
 # Whether the Xapian version in use supports field processors
 HAVE_XAPIAN_FIELD_PROCESSOR = ${have_xapian_field_processor}
 
+# Whether the Xapian version in use supports DB_RETRY_LOCK
+HAVE_XAPIAN_DB_RETRY_LOCK = ${have_xapian_db_retry_lock}
+
 # Whether the getpwuid_r function is standards-compliant
 # (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS
 # to enable the standards-compliant version -- needed for Solaris)
@@ -1097,6 +1128,7 @@ COMMON_CONFIGURE_CFLAGS = \\
        -DSTD_ASCTIME=\$(STD_ASCTIME)                           \\
        -DHAVE_XAPIAN_COMPACT=\$(HAVE_XAPIAN_COMPACT)           \\
        -DHAVE_XAPIAN_FIELD_PROCESSOR=\$(HAVE_XAPIAN_FIELD_PROCESSOR) \\
+       -DHAVE_XAPIAN_DB_RETRY_LOCK=\$(HAVE_XAPIAN_DB_RETRY_LOCK) \\
        -DUTIL_BYTE_ORDER=\$(UTIL_BYTE_ORDER)
 
 CONFIGURE_CFLAGS = \$(COMMON_CONFIGURE_CFLAGS)
@@ -1117,6 +1149,9 @@ NOTMUCH_HAVE_XAPIAN_COMPACT=${have_xapian_compact}
 # Whether the Xapian version in use supports field processors
 NOTMUCH_HAVE_XAPIAN_FIELD_PROCESSOR=${have_xapian_field_processor}
 
+# Whether the Xapian version in use supports lock retry
+NOTMUCH_HAVE_XAPIAN_DB_RETRY_LOCK=${have_xapian_db_retry_lock}
+
 # Which backend will Xapian use by default?
 NOTMUCH_DEFAULT_XAPIAN_BACKEND=${default_xapian_backend}
 
index afafe88cc08cfd6234f80309bb9ba6d7ae02c874..66ee267fe50ebb89b3e5feda2d4b88089d414800 100644 (file)
@@ -49,6 +49,12 @@ typedef struct {
 #define STRINGIFY(s) _SUB_STRINGIFY(s)
 #define _SUB_STRINGIFY(s) #s
 
+#if HAVE_XAPIAN_DB_RETRY_LOCK
+#define DB_ACTION (Xapian::DB_CREATE_OR_OPEN | Xapian::DB_RETRY_LOCK)
+#else
+#define DB_ACTION Xapian::DB_CREATE_OR_OPEN
+#endif
+
 /* Here's the current schema for our database (for NOTMUCH_DATABASE_VERSION):
  *
  * We currently have three different types of documents (mail, ghost,
@@ -939,7 +945,7 @@ notmuch_database_open_verbose (const char *path,
 
        if (mode == NOTMUCH_DATABASE_MODE_READ_WRITE) {
            notmuch->xapian_db = new Xapian::WritableDatabase (xapian_path,
-                                                              Xapian::DB_CREATE_OR_OPEN);
+                                                              DB_ACTION);
        } else {
            notmuch->xapian_db = new Xapian::Database (xapian_path);
        }