summaryrefslogtreecommitdiff
path: root/lib/libcrypto/err
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2003-11-11 22:15:21 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2003-11-11 22:15:21 +0000
commitbdb4cf312bb57e75d91c0b6c4b3b47fc10463260 (patch)
tree159bb0ea93999f8989ed1fc59ad8981ac286c1e1 /lib/libcrypto/err
parent122826059125660856e13fb3df457cb87744c415 (diff)
merge 0.9.7c; minor bugsfixes;
API addition: ERR_release_err_state_table [make includes before you build libssl/libcrypto]
Diffstat (limited to 'lib/libcrypto/err')
-rw-r--r--lib/libcrypto/err/err.c42
-rw-r--r--lib/libcrypto/err/err.h1
2 files changed, 42 insertions, 1 deletions
diff --git a/lib/libcrypto/err/err.c b/lib/libcrypto/err/err.c
index a4f4a260afa..6ab119c1ef6 100644
--- a/lib/libcrypto/err/err.c
+++ b/lib/libcrypto/err/err.c
@@ -225,6 +225,7 @@ struct st_ERR_FNS
ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *);
/* Works on the "thread_hash" error-state table */
LHASH *(*cb_thread_get)(int create);
+ void (*cb_thread_release)(LHASH **hash);
ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *);
ERR_STATE *(*cb_thread_set_item)(ERR_STATE *);
void (*cb_thread_del_item)(const ERR_STATE *);
@@ -239,6 +240,7 @@ static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *);
static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *);
static LHASH *int_thread_get(int create);
+static void int_thread_release(LHASH **hash);
static ERR_STATE *int_thread_get_item(const ERR_STATE *);
static ERR_STATE *int_thread_set_item(ERR_STATE *);
static void int_thread_del_item(const ERR_STATE *);
@@ -252,6 +254,7 @@ static const ERR_FNS err_defaults =
int_err_set_item,
int_err_del_item,
int_thread_get,
+ int_thread_release,
int_thread_get_item,
int_thread_set_item,
int_thread_del_item,
@@ -271,6 +274,7 @@ static const ERR_FNS *err_fns = NULL;
* and state in the loading application. */
static LHASH *int_error_hash = NULL;
static LHASH *int_thread_hash = NULL;
+static int int_thread_hash_references = 0;
static int int_err_library_number= ERR_LIB_USER;
/* Internal function that checks whether "err_fns" is set and if not, sets it to
@@ -417,11 +421,37 @@ static LHASH *int_thread_get(int create)
CRYPTO_pop_info();
}
if (int_thread_hash)
+ {
+ int_thread_hash_references++;
ret = int_thread_hash;
+ }
CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
return ret;
}
+static void int_thread_release(LHASH **hash)
+ {
+ int i;
+
+ if (hash == NULL || *hash == NULL)
+ return;
+
+ i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR);
+
+#ifdef REF_PRINT
+ fprintf(stderr,"%4d:%s\n",int_thread_hash_references,"ERR");
+#endif
+ if (i > 0) return;
+#ifdef REF_CHECK
+ if (i < 0)
+ {
+ fprintf(stderr,"int_thread_release, bad reference count\n");
+ abort(); /* ok */
+ }
+#endif
+ *hash = NULL;
+ }
+
static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
{
ERR_STATE *p;
@@ -436,6 +466,7 @@ static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
p = (ERR_STATE *)lh_retrieve(hash, d);
CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+ ERRFN(thread_release)(&hash);
return p;
}
@@ -453,6 +484,7 @@ static ERR_STATE *int_thread_set_item(ERR_STATE *d)
p = (ERR_STATE *)lh_insert(hash, d);
CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+ ERRFN(thread_release)(&hash);
return p;
}
@@ -469,13 +501,15 @@ static void int_thread_del_item(const ERR_STATE *d)
CRYPTO_w_lock(CRYPTO_LOCK_ERR);
p = (ERR_STATE *)lh_delete(hash, d);
/* make sure we don't leak memory */
- if (int_thread_hash && (lh_num_items(int_thread_hash) == 0))
+ if (int_thread_hash_references == 1
+ && int_thread_hash && (lh_num_items(int_thread_hash) == 0))
{
lh_free(int_thread_hash);
int_thread_hash = NULL;
}
CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+ ERRFN(thread_release)(&hash);
if (p)
ERR_STATE_free(p);
}
@@ -845,6 +879,12 @@ LHASH *ERR_get_err_state_table(void)
return ERRFN(thread_get)(0);
}
+void ERR_release_err_state_table(LHASH **hash)
+ {
+ err_fns_check();
+ ERRFN(thread_release)(hash);
+ }
+
const char *ERR_lib_error_string(unsigned long e)
{
ERR_STRING_DATA d,*p;
diff --git a/lib/libcrypto/err/err.h b/lib/libcrypto/err/err.h
index 988ef81aa0d..8faa3a7b4f5 100644
--- a/lib/libcrypto/err/err.h
+++ b/lib/libcrypto/err/err.h
@@ -278,6 +278,7 @@ ERR_STATE *ERR_get_state(void);
#ifndef OPENSSL_NO_LHASH
LHASH *ERR_get_string_table(void);
LHASH *ERR_get_err_state_table(void);
+void ERR_release_err_state_table(LHASH **hash);
#endif
int ERR_get_next_error_library(void);