Add reference counting around the thread state hash table.
Unfortunately, this means that the dynamic ENGINE version just went up, and isn't backward compatible. PR: 678
This commit is contained in:
parent
ba9f80c5d5
commit
11171f3c74
@ -226,6 +226,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 *);
|
||||
@ -240,6 +241,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 *);
|
||||
@ -253,6 +255,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,
|
||||
@ -272,6 +275,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
|
||||
@ -418,11 +422,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;
|
||||
@ -437,6 +467,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;
|
||||
}
|
||||
|
||||
@ -454,6 +485,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;
|
||||
}
|
||||
|
||||
@ -470,13 +502,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);
|
||||
}
|
||||
@ -855,6 +889,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;
|
||||
|
@ -293,6 +293,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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user