[Pkg-gnupg-commit] [gnupg2] 66/241: gpg: When the TOFU DB is in batch mode, periodically drop the locks.

Daniel Kahn Gillmor dkg at fifthhorseman.net
Wed Dec 9 20:31:55 UTC 2015


This is an automated email from the git hooks/post-receive script.

dkg pushed a commit to branch master
in repository gnupg2.

commit 5b0ed7674dc718ee98e0c80aa93ce014f2b51411
Author: Neal H. Walfield <neal at g10code.com>
Date:   Mon Oct 26 13:36:12 2015 +0100

    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 <neal at g10code.com>
---
 g10/tofu.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/g10/tofu.c b/g10/tofu.c
index ad61536..4eab487 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 ++;
 }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git



More information about the Pkg-gnupg-commit mailing list