aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeal H. Walfield <[email protected]>2015-10-26 12:36:12 +0000
committerNeal H. Walfield <[email protected]>2015-10-26 12:41:59 +0000
commit5b0ed7674dc718ee98e0c80aa93ce014f2b51411 (patch)
tree9d385a5465ba7e662b26a5b252a4928f92bcad9c
parentdirmngr: Add workaround for broken getaddrinfo. (diff)
downloadgnupg-5b0ed7674dc718ee98e0c80aa93ce014f2b51411.tar.gz
gnupg-5b0ed7674dc718ee98e0c80aa93ce014f2b51411.zip
gpg: When the TOFU DB is in batch mode, periodically drop the locks.
* g10/tofu.c: Include <sched.h>. (batch_update_started): New variable. (begin_transaction): If we've been in batch mode for a while, then commit any extant batch transactions. (tofu_begin_batch_update): If we are not in batch mode, initialize batch_update_started. -- Signed-off-by: Neal H. Walfield <[email protected]>
Diffstat (limited to '')
-rw-r--r--g10/tofu.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/g10/tofu.c b/g10/tofu.c
index ad615362e..4eab487b6 100644
--- a/g10/tofu.c
+++ b/g10/tofu.c
@@ -28,6 +28,7 @@
#include <sys/stat.h>
#include <assert.h>
#include <stdarg.h>
+#include <sched.h>
#include <sqlite3.h>
#include "gpg.h"
@@ -422,6 +423,9 @@ sqlite3_stepx (sqlite3 *db,
}
static int batch_update;
+static time_t batch_update_started;
+
+static gpg_error_t end_transaction (struct db *db, int only_batch);
/* Start a transaction on DB. */
static gpg_error_t
@@ -430,6 +434,29 @@ begin_transaction (struct db *db, int only_batch)
int rc;
char *err = NULL;
+ if (batch_update && batch_update_started != gnupg_get_time ())
+ /* We've been in batch update mode for a while (on average, more
+ than 500 ms). To prevent starving other gpg processes, we drop
+ and retake the batch lock.
+
+ Note: if we wanted higher resolution, we could use
+ npth_clock_gettime. */
+ {
+ struct db *t;
+
+ for (t = db_cache; t; t = t->next)
+ if (t->batch_update)
+ end_transaction (t, 1);
+ for (t = db; t; t = t->next)
+ if (t->batch_update)
+ end_transaction (t, 1);
+
+ batch_update_started = gnupg_get_time ();
+
+ /* Yield to allow another process a chance to run. */
+ sched_yield ();
+ }
+
/* XXX: In split mode, this can end in deadlock.
Consider: we have two gpg processes running simultaneously and
@@ -556,6 +583,9 @@ rollback_transaction (struct db *db)
void
tofu_begin_batch_update (void)
{
+ if (! batch_update)
+ batch_update_started = gnupg_get_time ();
+
batch_update ++;
}