g10: Make the keyblock cache per-handle rather than global.
authorNeal H. Walfield <neal@g10code.com>
Mon, 31 Aug 2015 11:57:07 +0000 (13:57 +0200)
committerNeal H. Walfield <neal@g10code.com>
Wed, 2 Sep 2015 08:52:01 +0000 (10:52 +0200)
* g10/keydb.c (keyblock_cache): Don't declare this variable.  Instead...
(struct keyblock_cache): ... turn its type into this first class
object...
(struct keydb_handle): ... and instantiate it once per database
handle.  Update all users.
(keydb_rebuild_caches): Don't invalidate the keyblock cache.

--
Signed-off-by: Neal H. Walfield <neal@g10code.com>.
g10/keydb.c

index 124e940..da18bc0 100644 (file)
@@ -62,6 +62,28 @@ static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
 static int used_resources;
 static void *primary_keyring=NULL;
 
+
+/* This is a simple cache used to return the last result of a
+   successful fingerprint search.  This works only for keybox resources
+   because (due to lack of a copy_keyblock function) we need to store
+   an image of the keyblock which is fortunately instantly available
+   for keyboxes.  */
+enum keyblock_cache_states {
+  KEYBLOCK_CACHE_EMPTY,
+  KEYBLOCK_CACHE_PREPARED,
+  KEYBLOCK_CACHE_FILLED
+};
+
+struct keyblock_cache {
+  enum keyblock_cache_states state;
+  byte fpr[MAX_FINGERPRINT_LEN];
+  iobuf_t iobuf; /* Image of the keyblock.  */
+  u32 *sigstatus;
+  int pk_no;
+  int uid_no;
+};
+
+
 struct keydb_handle
 {
   /* When we locked all of the resources in ACTIVE (using keyring_lock
@@ -94,6 +116,10 @@ struct keydb_handle
   /* The number of resources in ACTIVE.  */
   int used;
 
+  /* Cache of the last found and parsed key block (only used for
+     keyboxes, not keyrings).  */
+  struct keyblock_cache keyblock_cache;
+
   /* Copy of ALL_RESOURCES when keydb_new is called.  */
   struct resource_item active[MAX_KEYDB_RESOURCES];
 };
@@ -126,27 +152,6 @@ struct kid_not_found_cache_bucket
 };
 
 
-/* This is a simple cache used to return the last result of a
-   successful fingerprint search.  This works only for keybox resources
-   because (due to lack of a copy_keyblock function) we need to store
-   an image of the keyblock which is fortunately instantly available
-   for keyboxes.  */
-enum keyblock_cache_states {
-  KEYBLOCK_CACHE_EMPTY,
-  KEYBLOCK_CACHE_PREPARED,
-  KEYBLOCK_CACHE_FILLED
-};
-
-struct {
-  enum keyblock_cache_states state;
-  byte fpr[MAX_FINGERPRINT_LEN];
-  iobuf_t iobuf; /* Image of the keyblock.  */
-  u32 *sigstatus;
-  int pk_no;
-  int uid_no;
-} keyblock_cache;
-
-
 static int lock_all (KEYDB_HANDLE hd);
 static void unlock_all (KEYDB_HANDLE hd);
 
@@ -233,13 +238,13 @@ kid_not_found_flush (void)
 
 
 static void
-keyblock_cache_clear (void)
+keyblock_cache_clear (struct keydb_handle *hd)
 {
-  keyblock_cache.state = KEYBLOCK_CACHE_EMPTY;
-  xfree (keyblock_cache.sigstatus);
-  keyblock_cache.sigstatus = NULL;
-  iobuf_close (keyblock_cache.iobuf);
-  keyblock_cache.iobuf = NULL;
+  hd->keyblock_cache.state = KEYBLOCK_CACHE_EMPTY;
+  xfree (hd->keyblock_cache.sigstatus);
+  hd->keyblock_cache.sigstatus = NULL;
+  iobuf_close (hd->keyblock_cache.iobuf);
+  hd->keyblock_cache.iobuf = NULL;
 }
 
 
@@ -1124,23 +1129,23 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
   if (DBG_CLOCK)
     log_clock ("keydb_get_keybock enter");
 
-  if (keyblock_cache.state == KEYBLOCK_CACHE_FILLED)
+  if (hd->keyblock_cache.state == KEYBLOCK_CACHE_FILLED)
     {
-      err = iobuf_seek (keyblock_cache.iobuf, 0);
+      err = iobuf_seek (hd->keyblock_cache.iobuf, 0);
       if (err)
        {
          log_error ("keydb_get_keyblock: failed to rewind iobuf for cache\n");
-         keyblock_cache_clear ();
+         keyblock_cache_clear (hd);
        }
       else
        {
-         err = parse_keyblock_image (keyblock_cache.iobuf,
-                                     keyblock_cache.pk_no,
-                                     keyblock_cache.uid_no,
-                                     keyblock_cache.sigstatus,
+         err = parse_keyblock_image (hd->keyblock_cache.iobuf,
+                                     hd->keyblock_cache.pk_no,
+                                     hd->keyblock_cache.uid_no,
+                                     hd->keyblock_cache.sigstatus,
                                      ret_kb);
          if (err)
-           keyblock_cache_clear ();
+           keyblock_cache_clear (hd);
          if (DBG_CLOCK)
            log_clock (err? "keydb_get_keyblock leave (cached, failed)"
                       : "keydb_get_keyblock leave (cached)");
@@ -1171,13 +1176,13 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
           {
             err = parse_keyblock_image (iobuf, pk_no, uid_no, sigstatus,
                                         ret_kb);
-            if (!err && keyblock_cache.state == KEYBLOCK_CACHE_PREPARED)
+            if (!err && hd->keyblock_cache.state == KEYBLOCK_CACHE_PREPARED)
               {
-                keyblock_cache.state     = KEYBLOCK_CACHE_FILLED;
-                keyblock_cache.sigstatus = sigstatus;
-                keyblock_cache.iobuf     = iobuf;
-                keyblock_cache.pk_no     = pk_no;
-                keyblock_cache.uid_no    = uid_no;
+                hd->keyblock_cache.state     = KEYBLOCK_CACHE_FILLED;
+                hd->keyblock_cache.sigstatus = sigstatus;
+                hd->keyblock_cache.iobuf     = iobuf;
+                hd->keyblock_cache.pk_no     = pk_no;
+                hd->keyblock_cache.uid_no    = uid_no;
               }
             else
               {
@@ -1189,8 +1194,8 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
       break;
     }
 
-  if (keyblock_cache.state != KEYBLOCK_CACHE_FILLED)
-    keyblock_cache_clear ();
+  if (hd->keyblock_cache.state != KEYBLOCK_CACHE_FILLED)
+    keyblock_cache_clear (hd);
 
   if (DBG_CLOCK)
     log_clock (err? "keydb_get_keyblock leave (failed)"
@@ -1298,7 +1303,7 @@ keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
     return gpg_error (GPG_ERR_INV_ARG);
 
   kid_not_found_flush ();
-  keyblock_cache_clear ();
+  keyblock_cache_clear (hd);
 
   if (hd->found < 0 || hd->found >= hd->used)
     return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
@@ -1349,7 +1354,7 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
     return gpg_error (GPG_ERR_INV_ARG);
 
   kid_not_found_flush ();
-  keyblock_cache_clear ();
+  keyblock_cache_clear (hd);
 
   if (opt.dry_run)
     return 0;
@@ -1409,7 +1414,7 @@ keydb_delete_keyblock (KEYDB_HANDLE hd)
     return gpg_error (GPG_ERR_INV_ARG);
 
   kid_not_found_flush ();
-  keyblock_cache_clear ();
+  keyblock_cache_clear (hd);
 
   if (hd->found < 0 || hd->found >= hd->used)
     return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
@@ -1497,8 +1502,6 @@ keydb_rebuild_caches (int noisy)
 {
   int i, rc;
 
-  keyblock_cache_clear ();
-
   for (i=0; i < used_resources; i++)
     {
       if (!keyring_is_writable (all_resources[i].token))
@@ -1537,7 +1540,7 @@ keydb_search_reset (KEYDB_HANDLE hd)
   if (!hd)
     return gpg_error (GPG_ERR_INV_ARG);
 
-  keyblock_cache_clear ();
+  keyblock_cache_clear (hd);
 
   if (DBG_CLOCK)
     log_clock ("keydb_search_reset");
@@ -1652,8 +1655,8 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
       && ndesc == 1
       && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
           || desc[0].mode == KEYDB_SEARCH_MODE_FPR)
-      && keyblock_cache.state  == KEYBLOCK_CACHE_FILLED
-      && !memcmp (keyblock_cache.fpr, desc[0].u.fpr, 20))
+      && hd->keyblock_cache.state  == KEYBLOCK_CACHE_FILLED
+      && !memcmp (hd->keyblock_cache.fpr, desc[0].u.fpr, 20))
     {
       /* (DESCINDEX is already set).  */
       if (DBG_CLOCK)
@@ -1694,14 +1697,14 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
         ? gpg_error (GPG_ERR_NOT_FOUND)
         : rc);
 
-  keyblock_cache_clear ();
+  keyblock_cache_clear (hd);
   if (!hd->no_caching
       && !rc
       && ndesc == 1 && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
                         || desc[0].mode == KEYDB_SEARCH_MODE_FPR))
     {
-      keyblock_cache.state = KEYBLOCK_CACHE_PREPARED;
-      memcpy (keyblock_cache.fpr, desc[0].u.fpr, 20);
+      hd->keyblock_cache.state = KEYBLOCK_CACHE_PREPARED;
+      memcpy (hd->keyblock_cache.fpr, desc[0].u.fpr, 20);
     }
 
   if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND