base/SOURCES/libgcrypt-1.5.3-ath-reinsta...

134 lines
2.9 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

diff -up libgcrypt-1.5.3/src/ath.c.ath-reinstall libgcrypt-1.5.3/src/ath.c
--- libgcrypt-1.5.3/src/ath.c.ath-reinstall 2013-07-25 11:10:04.000000000 +0200
+++ libgcrypt-1.5.3/src/ath.c 2017-02-28 14:37:15.267668432 +0100
@@ -36,7 +36,7 @@
#include <errno.h>
#include "ath.h"
-
+#include "g10lib.h"
/* The interface table. */
@@ -45,6 +45,13 @@ static struct ath_ops ops;
/* True if we should use the external callbacks. */
static int ops_set;
+struct lock_list
+{
+ ath_mutex_t *lock;
+ struct lock_list *next;
+};
+
+static struct lock_list *reinstallable_locks;
/* For the dummy interface. */
#define MUTEX_UNLOCKED ((ath_mutex_t) 0)
@@ -62,6 +69,50 @@ static int ops_set;
/* The lock we take while checking for lazy lock initialization. */
static ath_mutex_t check_init_lock = ATH_MUTEX_INITIALIZER;
+static void
+add_reinstallable_lock(ath_mutex_t *lock)
+{
+ struct lock_list *ll, *new, **ptr;
+
+ new = gcry_calloc(1, sizeof(*new));
+ if (!new)
+ abort();
+
+ for (ll = reinstallable_locks, ptr = &reinstallable_locks; ll != NULL; ptr = &ll->next, ll = ll->next)
+ {
+ if (ll->lock == lock)
+ {
+ gcry_free(new);
+ return;
+ }
+ }
+
+ new->lock = lock;
+ *ptr = new;
+}
+
+static void
+remove_reinstallable_lock(ath_mutex_t *lock)
+{
+ struct lock_list *ll, **ptr;
+
+ for (ll = reinstallable_locks, ptr = &reinstallable_locks; ll != NULL; ptr = &ll->next, ll = ll->next)
+ {
+ if (ll->lock == lock)
+ {
+ *ptr = ll->next;
+ gcry_free(ll);
+ /* we do not store duplicates */
+ return;
+ }
+ }
+
+#ifndef NDEBUG
+ /* lock not found, should not happen */
+ abort();
+#endif
+}
+
int
ath_init (void)
{
@@ -85,7 +136,9 @@ ath_init (void)
gpg_err_code_t
ath_install (struct ath_ops *ath_ops, int check_only)
{
- if (check_only)
+ gpg_err_code_t err = 0;
+
+ if (check_only && ops_set)
{
unsigned int option = 0;
@@ -119,7 +172,25 @@ ath_install (struct ath_ops *ath_ops, in
else
ops_set = 0;
- return 0;
+ if (ops_set && reinstallable_locks)
+ {
+ struct lock_list *ll;
+
+ ath_init();
+ for (ll = reinstallable_locks; ll != NULL;)
+ {
+ struct lock_list *prev;
+
+ if (ath_mutex_init(ll->lock))
+ err = GPG_ERR_NOT_SUPPORTED;
+ prev = ll;
+ ll = ll->next;
+ gcry_free(prev);
+ }
+ reinstallable_locks = NULL;
+ }
+
+ return err;
}
@@ -143,6 +214,8 @@ ath_mutex_init (ath_mutex_t *lock)
{
if (ops_set)
return mutex_init (lock, 0);
+ else
+ add_reinstallable_lock(lock);
#ifndef NDEBUG
*lock = MUTEX_UNLOCKED;
@@ -168,6 +241,8 @@ ath_mutex_destroy (ath_mutex_t *lock)
(*ops.mutex_unlock) (&check_init_lock);
return (*ops.mutex_destroy) (lock);
}
+ else
+ remove_reinstallable_lock(lock);
#ifndef NDEBUG
assert (*lock == MUTEX_UNLOCKED);