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 | #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 | #ifndef FIPS_MODULE | ||||||
| /*
 | /*
 | ||||||
|  * Since per-thread-specific-data destructors are not universally |  * Since per-thread-specific-data destructors are not universally | ||||||
|  | @ -167,6 +103,81 @@ static union { | ||||||
|     CRYPTO_THREAD_LOCAL value; |     CRYPTO_THREAD_LOCAL value; | ||||||
| } destructor_key = { -1 }; | } 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 |  * The thread event handler list is a thread specific linked list | ||||||
|  * of callback functions which are invoked in list order by the |  * 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) | void OPENSSL_thread_stop(void) | ||||||
| { | { | ||||||
|     if (destructor_key.sane != -1) { |     if (destructor_key.sane != -1) { | ||||||
|         THREAD_EVENT_HANDLER **hands |         THREAD_EVENT_HANDLER **hands = init_fetch_clear_thread_local(NULL); | ||||||
|             = init_get_thread_local(&destructor_key.value, 0, 0); | 
 | ||||||
|         init_thread_stop(NULL, hands); |         init_thread_stop(NULL, hands); | ||||||
| 
 | 
 | ||||||
|         init_thread_remove_handlers(hands); |         init_thread_remove_handlers(hands); | ||||||
|  | @ -267,8 +278,8 @@ void OPENSSL_thread_stop(void) | ||||||
| void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx) | void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx) | ||||||
| { | { | ||||||
|     if (destructor_key.sane != -1) { |     if (destructor_key.sane != -1) { | ||||||
|         THREAD_EVENT_HANDLER **hands |         THREAD_EVENT_HANDLER **hands = init_fetch_thread_local(ctx); | ||||||
|             = init_get_thread_local(&destructor_key.value, 0, 1); | 
 | ||||||
|         init_thread_stop(ctx, hands); |         init_thread_stop(ctx, hands); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -325,7 +336,7 @@ void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx) | ||||||
| { | { | ||||||
|     THREAD_EVENT_HANDLER **hands; |     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); |     init_thread_stop(ctx, hands); | ||||||
|     OPENSSL_free(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 **hands; | ||||||
|     THREAD_EVENT_HANDLER *hand; |     THREAD_EVENT_HANDLER *hand; | ||||||
|  |     OSSL_LIB_CTX *ctx = NULL; | ||||||
| #ifdef FIPS_MODULE | #ifdef FIPS_MODULE | ||||||
|     OSSL_LIB_CTX *ctx = arg; |  | ||||||
| 
 |  | ||||||
|     /*
 |     /*
 | ||||||
|      * In FIPS mode the list of THREAD_EVENT_HANDLERs is unique per combination |      * 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 |      * of OSSL_LIB_CTX and thread. This is because in FIPS mode each | ||||||
|      * OSSL_LIB_CTX gets informed about thread stop events individually. |      * OSSL_LIB_CTX gets informed about thread stop events individually. | ||||||
|      */ |      */ | ||||||
|     hands = init_get_thread_local_ex(ctx, 1, 0); | 
 | ||||||
| #else |     ctx = arg; | ||||||
|     /*
 |  | ||||||
|      * 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); |  | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  |     hands = init_fetch_alloc_thread_local(ctx); | ||||||
|  | 
 | ||||||
|     if (hands == NULL) |     if (hands == NULL) | ||||||
|         return 0; |         return 0; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue