diff options
author | Neal H. Walfield <[email protected]> | 2015-10-26 12:36:12 +0000 |
---|---|---|
committer | Neal H. Walfield <[email protected]> | 2015-10-26 12:41:59 +0000 |
commit | 5b0ed7674dc718ee98e0c80aa93ce014f2b51411 (patch) | |
tree | 9d385a5465ba7e662b26a5b252a4928f92bcad9c | |
parent | dirmngr: Add workaround for broken getaddrinfo. (diff) | |
download | gnupg-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.c | 30 |
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 ++; } |