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
88fd7424f6
commit
732d1bf43a
@ -538,10 +538,10 @@ void ENGINE_add_conf_module(void);
|
||||
/**************************/
|
||||
|
||||
/* Binary/behaviour compatibility levels */
|
||||
#define OSSL_DYNAMIC_VERSION (unsigned long)0x00010100
|
||||
#define OSSL_DYNAMIC_VERSION (unsigned long)0x00010200
|
||||
/* Binary versions older than this are too old for us (whether we're a loader or
|
||||
* a loadee) */
|
||||
#define OSSL_DYNAMIC_OLDEST (unsigned long)0x00010100
|
||||
#define OSSL_DYNAMIC_OLDEST (unsigned long)0x00010200
|
||||
|
||||
/* When compiling an ENGINE entirely as an external shared library, loadable by
|
||||
* the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user