mirror of https://github.com/openssl/openssl.git
Refactor init_get_thread_local to be more understandable
We currently have a single function that does thread_local key allocation/cleanup/fetching for our OSSL_init_thread_start/stop apis, and its pretty confusing. Wrap it up in some helper functions to make it more clear at the call sites what we're trying to do. Reviewed-by: Saša Nedvědický <sashan@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/27794)
This commit is contained in:
parent
5466197f16
commit
d259b8b855
|
|
@ -83,70 +83,6 @@ static GLOBAL_TEVENT_REGISTER *get_global_tevent_register(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef FIPS_MODULE
|
||||
static int init_thread_push_handlers(THREAD_EVENT_HANDLER **hands);
|
||||
static void init_thread_remove_handlers(THREAD_EVENT_HANDLER **handsin);
|
||||
static void init_thread_destructor(void *hands);
|
||||
static int init_thread_deregister(void *arg, int all);
|
||||
#endif
|
||||
static void init_thread_stop(void *arg, THREAD_EVENT_HANDLER **hands);
|
||||
|
||||
#ifndef FIPS_MODULE
|
||||
static THREAD_EVENT_HANDLER **
|
||||
init_get_thread_local(CRYPTO_THREAD_LOCAL *local, int alloc, int keep)
|
||||
{
|
||||
THREAD_EVENT_HANDLER **hands = CRYPTO_THREAD_get_local(local);
|
||||
|
||||
if (alloc) {
|
||||
if (hands == NULL) {
|
||||
|
||||
if ((hands = OPENSSL_zalloc(sizeof(*hands))) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!CRYPTO_THREAD_set_local(local, hands)) {
|
||||
OPENSSL_free(hands);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!init_thread_push_handlers(hands)) {
|
||||
CRYPTO_THREAD_set_local(local, NULL);
|
||||
OPENSSL_free(hands);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
} else if (!keep) {
|
||||
CRYPTO_THREAD_set_local(local, NULL);
|
||||
}
|
||||
|
||||
return hands;
|
||||
}
|
||||
|
||||
#else
|
||||
static THREAD_EVENT_HANDLER **
|
||||
init_get_thread_local_ex(OSSL_LIB_CTX *ctx, int alloc, int keep)
|
||||
{
|
||||
THREAD_EVENT_HANDLER **hands = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_TEVENT_KEY, ctx);
|
||||
|
||||
if (alloc) {
|
||||
if (hands == NULL) {
|
||||
|
||||
if ((hands = OPENSSL_zalloc(sizeof(*hands))) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_TEVENT_KEY, ctx, hands)) {
|
||||
OPENSSL_free(hands);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
} else if (!keep) {
|
||||
CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_TEVENT_KEY, ctx, NULL);
|
||||
}
|
||||
|
||||
return hands;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef FIPS_MODULE
|
||||
/*
|
||||
* Since per-thread-specific-data destructors are not universally
|
||||
|
|
@ -167,6 +103,81 @@ static union {
|
|||
CRYPTO_THREAD_LOCAL value;
|
||||
} destructor_key = { -1 };
|
||||
|
||||
static int init_thread_push_handlers(THREAD_EVENT_HANDLER **hands);
|
||||
static void init_thread_remove_handlers(THREAD_EVENT_HANDLER **handsin);
|
||||
static void init_thread_destructor(void *hands);
|
||||
static int init_thread_deregister(void *arg, int all);
|
||||
#endif
|
||||
static void init_thread_stop(void *arg, THREAD_EVENT_HANDLER **hands);
|
||||
|
||||
static THREAD_EVENT_HANDLER ** get_thread_event_handler(OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
#ifdef FIPS_MODULE
|
||||
return CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_TEVENT_KEY, ctx);
|
||||
#else
|
||||
if (destructor_key.sane != -1)
|
||||
return CRYPTO_THREAD_get_local(&destructor_key.value);
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int set_thread_event_handler(OSSL_LIB_CTX *ctx, THREAD_EVENT_HANDLER **hands)
|
||||
{
|
||||
#ifdef FIPS_MODULE
|
||||
return CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_TEVENT_KEY, ctx, hands);
|
||||
#else
|
||||
if (destructor_key.sane != -1)
|
||||
return CRYPTO_THREAD_set_local(&destructor_key.value, hands);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static THREAD_EVENT_HANDLER **
|
||||
init_manage_thread_local(OSSL_LIB_CTX *ctx, int alloc, int keep)
|
||||
{
|
||||
THREAD_EVENT_HANDLER **hands = get_thread_event_handler(ctx);
|
||||
|
||||
if (alloc) {
|
||||
if (hands == NULL) {
|
||||
|
||||
if ((hands = OPENSSL_zalloc(sizeof(*hands))) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!set_thread_event_handler(ctx, hands)) {
|
||||
OPENSSL_free(hands);
|
||||
return NULL;
|
||||
}
|
||||
#ifndef FIPS_MODULE
|
||||
if (!init_thread_push_handlers(hands)) {
|
||||
set_thread_event_handler(ctx, NULL);
|
||||
OPENSSL_free(hands);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else if (!keep) {
|
||||
set_thread_event_handler(ctx, NULL);
|
||||
}
|
||||
|
||||
return hands;
|
||||
}
|
||||
|
||||
static ossl_inline THREAD_EVENT_HANDLER **init_fetch_clear_thread_local(OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
return init_manage_thread_local(ctx, 0, 0);
|
||||
}
|
||||
|
||||
static ossl_inline ossl_unused THREAD_EVENT_HANDLER **init_fetch_thread_local(OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
return init_manage_thread_local(ctx, 0, 1);
|
||||
}
|
||||
|
||||
static ossl_inline THREAD_EVENT_HANDLER **init_fetch_alloc_thread_local(OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
return init_manage_thread_local(ctx, 1, 0);
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODULE
|
||||
/*
|
||||
* The thread event handler list is a thread specific linked list
|
||||
* of callback functions which are invoked in list order by the
|
||||
|
|
@ -255,8 +266,8 @@ void OPENSSL_thread_stop_ex(OSSL_LIB_CTX *ctx)
|
|||
void OPENSSL_thread_stop(void)
|
||||
{
|
||||
if (destructor_key.sane != -1) {
|
||||
THREAD_EVENT_HANDLER **hands
|
||||
= init_get_thread_local(&destructor_key.value, 0, 0);
|
||||
THREAD_EVENT_HANDLER **hands = init_fetch_clear_thread_local(NULL);
|
||||
|
||||
init_thread_stop(NULL, hands);
|
||||
|
||||
init_thread_remove_handlers(hands);
|
||||
|
|
@ -267,8 +278,8 @@ void OPENSSL_thread_stop(void)
|
|||
void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
if (destructor_key.sane != -1) {
|
||||
THREAD_EVENT_HANDLER **hands
|
||||
= init_get_thread_local(&destructor_key.value, 0, 1);
|
||||
THREAD_EVENT_HANDLER **hands = init_fetch_thread_local(ctx);
|
||||
|
||||
init_thread_stop(ctx, hands);
|
||||
}
|
||||
}
|
||||
|
|
@ -325,7 +336,7 @@ void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx)
|
|||
{
|
||||
THREAD_EVENT_HANDLER **hands;
|
||||
|
||||
hands = init_get_thread_local_ex(ctx, 0, 0);
|
||||
hands = init_fetch_clear_thread_local(ctx);
|
||||
init_thread_stop(ctx, hands);
|
||||
OPENSSL_free(hands);
|
||||
}
|
||||
|
|
@ -380,26 +391,19 @@ int ossl_init_thread_start(const void *index, void *arg,
|
|||
{
|
||||
THREAD_EVENT_HANDLER **hands;
|
||||
THREAD_EVENT_HANDLER *hand;
|
||||
OSSL_LIB_CTX *ctx = NULL;
|
||||
#ifdef FIPS_MODULE
|
||||
OSSL_LIB_CTX *ctx = arg;
|
||||
|
||||
/*
|
||||
* In FIPS mode the list of THREAD_EVENT_HANDLERs is unique per combination
|
||||
* of OSSL_LIB_CTX and thread. This is because in FIPS mode each
|
||||
* OSSL_LIB_CTX gets informed about thread stop events individually.
|
||||
*/
|
||||
hands = init_get_thread_local_ex(ctx, 1, 0);
|
||||
#else
|
||||
/*
|
||||
* Outside of FIPS mode the list of THREAD_EVENT_HANDLERs is unique per
|
||||
* thread, but may hold multiple OSSL_LIB_CTXs. We only get told about
|
||||
* thread stop events globally, so we have to ensure all affected
|
||||
* OSSL_LIB_CTXs are informed.
|
||||
*/
|
||||
CRYPTO_THREAD_LOCAL *local = &destructor_key.value;
|
||||
hands = init_get_thread_local(local, 1, 0);
|
||||
|
||||
ctx = arg;
|
||||
#endif
|
||||
|
||||
hands = init_fetch_alloc_thread_local(ctx);
|
||||
|
||||
if (hands == NULL)
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue