| 
									
										
										
										
											2016-07-20 01:38:57 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2021-01-28 20:54:57 +08:00
										 |  |  |  * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2016-07-20 01:38:57 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-12-06 20:12:35 +08:00
										 |  |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use | 
					
						
							| 
									
										
										
										
											2016-07-20 01:38:57 +08:00
										 |  |  |  * this file except in compliance with the License.  You can obtain a copy | 
					
						
							|  |  |  |  * in the file LICENSE in the source distribution or at | 
					
						
							|  |  |  |  * https://www.openssl.org/source/license.html
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-07 05:14:03 +08:00
										 |  |  | #ifndef OSSL_INTERNAL_THREAD_ONCE_H
 | 
					
						
							|  |  |  | # define OSSL_INTERNAL_THREAD_ONCE_H
 | 
					
						
							|  |  |  | # pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # include <openssl/crypto.h>
 | 
					
						
							| 
									
										
										
										
											2016-07-20 01:38:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-04 17:21:53 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Initialisation of global data should never happen via "RUN_ONCE" inside the | 
					
						
							|  |  |  |  * FIPS module. Global data should instead always be associated with a specific | 
					
						
							| 
									
										
										
										
											2020-10-15 17:55:50 +08:00
										 |  |  |  * OSSL_LIB_CTX object. In this way data will get cleaned up correctly when the | 
					
						
							| 
									
										
										
										
											2019-07-04 17:21:53 +08:00
										 |  |  |  * module gets unloaded. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-02-07 05:14:03 +08:00
										 |  |  | # if !defined(FIPS_MODULE) || defined(ALLOW_RUN_ONCE_IN_FIPS)
 | 
					
						
							| 
									
										
										
										
											2018-11-20 23:32:55 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * DEFINE_RUN_ONCE: Define an initialiser function that should be run exactly | 
					
						
							| 
									
										
										
										
											2021-01-26 16:19:03 +08:00
										 |  |  |  * once. It takes no arguments and returns an int result (1 for success or | 
					
						
							| 
									
										
										
										
											2018-11-20 23:32:55 +08:00
										 |  |  |  * 0 for failure). Typical usage might be: | 
					
						
							| 
									
										
										
										
											2019-02-01 01:55:30 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-11-20 23:32:55 +08:00
										 |  |  |  * DEFINE_RUN_ONCE(myinitfunc) | 
					
						
							|  |  |  |  * { | 
					
						
							|  |  |  |  *     do_some_initialisation(); | 
					
						
							|  |  |  |  *     if (init_is_successful()) | 
					
						
							|  |  |  |  *         return 1; | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     return 0; | 
					
						
							|  |  |  |  * } | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-02-07 05:14:03 +08:00
										 |  |  | #  define DEFINE_RUN_ONCE(init)                   \
 | 
					
						
							| 
									
										
										
										
											2016-07-20 01:38:57 +08:00
										 |  |  |     static int init(void);                     \ | 
					
						
							|  |  |  |     int init##_ossl_ret_ = 0;                   \ | 
					
						
							|  |  |  |     void init##_ossl_(void)                     \ | 
					
						
							|  |  |  |     {                                           \ | 
					
						
							|  |  |  |         init##_ossl_ret_ = init();              \ | 
					
						
							|  |  |  |     }                                           \ | 
					
						
							|  |  |  |     static int init(void) | 
					
						
							| 
									
										
										
										
											2018-11-20 23:32:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * DECLARE_RUN_ONCE: Declare an initialiser function that should be run exactly | 
					
						
							|  |  |  |  * once that has been defined in another file via DEFINE_RUN_ONCE(). | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-02-07 05:14:03 +08:00
										 |  |  | #  define DECLARE_RUN_ONCE(init)                  \
 | 
					
						
							| 
									
										
										
										
											2016-07-20 01:38:57 +08:00
										 |  |  |     extern int init##_ossl_ret_;                \ | 
					
						
							|  |  |  |     void init##_ossl_(void); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 23:32:55 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * DEFINE_RUN_ONCE_STATIC: Define an initialiser function that should be run | 
					
						
							|  |  |  |  * exactly once. This function will be declared as static within the file. It | 
					
						
							| 
									
										
										
										
											2021-01-26 16:19:03 +08:00
										 |  |  |  * takes no arguments and returns an int result (1 for success or 0 for | 
					
						
							| 
									
										
										
										
											2018-11-20 23:32:55 +08:00
										 |  |  |  * failure). Typical usage might be: | 
					
						
							| 
									
										
										
										
											2019-02-01 01:55:30 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-11-20 23:32:55 +08:00
										 |  |  |  * DEFINE_RUN_ONCE_STATIC(myinitfunc) | 
					
						
							|  |  |  |  * { | 
					
						
							|  |  |  |  *     do_some_initialisation(); | 
					
						
							|  |  |  |  *     if (init_is_successful()) | 
					
						
							|  |  |  |  *         return 1; | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     return 0; | 
					
						
							|  |  |  |  * } | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-02-07 05:14:03 +08:00
										 |  |  | #  define DEFINE_RUN_ONCE_STATIC(init)            \
 | 
					
						
							| 
									
										
										
										
											2016-07-20 01:38:57 +08:00
										 |  |  |     static int init(void);                     \ | 
					
						
							|  |  |  |     static int init##_ossl_ret_ = 0;            \ | 
					
						
							|  |  |  |     static void init##_ossl_(void)              \ | 
					
						
							|  |  |  |     {                                           \ | 
					
						
							|  |  |  |         init##_ossl_ret_ = init();              \ | 
					
						
							|  |  |  |     }                                           \ | 
					
						
							|  |  |  |     static int init(void) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 23:32:55 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * DEFINE_RUN_ONCE_STATIC_ALT: Define an alternative initialiser function. This | 
					
						
							|  |  |  |  * function will be declared as static within the file. It takes no arguments | 
					
						
							| 
									
										
										
										
											2021-01-26 16:19:03 +08:00
										 |  |  |  * and returns an int result (1 for success or 0 for failure). An alternative | 
					
						
							| 
									
										
										
										
											2018-11-20 23:32:55 +08:00
										 |  |  |  * initialiser function is expected to be associated with a primary initialiser | 
					
						
							|  |  |  |  * function defined via DEFINE_ONCE_STATIC where both functions use the same | 
					
						
							|  |  |  |  * CRYPTO_ONCE object to synchronise. Where an alternative initialiser function | 
					
						
							|  |  |  |  * is used only one of the primary or the alternative initialiser function will | 
					
						
							| 
									
										
										
										
											2019-07-02 16:04:04 +08:00
										 |  |  |  * ever be called - and that function will be called exactly once. Definition | 
					
						
							| 
									
										
										
										
											2018-11-20 23:32:55 +08:00
										 |  |  |  * of an alternative initialiser function MUST occur AFTER the definition of the | 
					
						
							| 
									
										
										
										
											2019-07-02 16:04:04 +08:00
										 |  |  |  * primary initialiser function. | 
					
						
							| 
									
										
										
										
											2019-02-01 01:55:30 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-11-20 23:32:55 +08:00
										 |  |  |  * Typical usage might be: | 
					
						
							| 
									
										
										
										
											2019-02-01 01:55:30 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-11-20 23:32:55 +08:00
										 |  |  |  * DEFINE_RUN_ONCE_STATIC(myinitfunc) | 
					
						
							|  |  |  |  * { | 
					
						
							|  |  |  |  *     do_some_initialisation(); | 
					
						
							|  |  |  |  *     if (init_is_successful()) | 
					
						
							|  |  |  |  *         return 1; | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     return 0; | 
					
						
							|  |  |  |  * } | 
					
						
							| 
									
										
										
										
											2019-02-01 01:55:30 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-11-20 23:32:55 +08:00
										 |  |  |  * DEFINE_RUN_ONCE_STATIC_ALT(myaltinitfunc, myinitfunc) | 
					
						
							|  |  |  |  * { | 
					
						
							|  |  |  |  *     do_some_alternative_initialisation(); | 
					
						
							|  |  |  |  *     if (init_is_successful()) | 
					
						
							|  |  |  |  *         return 1; | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     return 0; | 
					
						
							|  |  |  |  * } | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-02-07 05:14:03 +08:00
										 |  |  | #  define DEFINE_RUN_ONCE_STATIC_ALT(initalt, init) \
 | 
					
						
							| 
									
										
										
										
											2018-11-20 23:32:55 +08:00
										 |  |  |     static int initalt(void);                     \ | 
					
						
							|  |  |  |     static void initalt##_ossl_(void)             \ | 
					
						
							|  |  |  |     {                                             \ | 
					
						
							|  |  |  |         init##_ossl_ret_ = initalt();             \ | 
					
						
							|  |  |  |     }                                             \ | 
					
						
							|  |  |  |     static int initalt(void) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-20 01:38:57 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * RUN_ONCE - use CRYPTO_THREAD_run_once, and check if the init succeeded | 
					
						
							|  |  |  |  * @once: pointer to static object of type CRYPTO_ONCE | 
					
						
							|  |  |  |  * @init: function name that was previously given to DEFINE_RUN_ONCE, | 
					
						
							| 
									
										
										
										
											2017-01-13 06:13:17 +08:00
										 |  |  |  *        DEFINE_RUN_ONCE_STATIC or DECLARE_RUN_ONCE.  This function | 
					
						
							|  |  |  |  *        must return 1 for success or 0 for failure. | 
					
						
							| 
									
										
										
										
											2016-07-20 01:38:57 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2017-01-13 06:13:17 +08:00
										 |  |  |  * The return value is 1 on success (*) or 0 in case of error. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * (*) by convention, since the init function must return 1 on success. | 
					
						
							| 
									
										
										
										
											2016-07-20 01:38:57 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-02-07 05:14:03 +08:00
										 |  |  | #  define RUN_ONCE(once, init)                                            \
 | 
					
						
							| 
									
										
										
										
											2016-07-20 01:38:57 +08:00
										 |  |  |     (CRYPTO_THREAD_run_once(once, init##_ossl_) ? init##_ossl_ret_ : 0) | 
					
						
							| 
									
										
										
										
											2018-11-20 23:32:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * RUN_ONCE_ALT - use CRYPTO_THREAD_run_once, to run an alternative initialiser | 
					
						
							|  |  |  |  *                function and check if that initialisation succeeded | 
					
						
							|  |  |  |  * @once:    pointer to static object of type CRYPTO_ONCE | 
					
						
							|  |  |  |  * @initalt: alternative initialiser function name that was previously given to | 
					
						
							|  |  |  |  *           DEFINE_RUN_ONCE_STATIC_ALT.  This function must return 1 for | 
					
						
							|  |  |  |  *           success or 0 for failure. | 
					
						
							|  |  |  |  * @init:    primary initialiser function name that was previously given to | 
					
						
							|  |  |  |  *           DEFINE_RUN_ONCE_STATIC.  This function must return 1 for success or | 
					
						
							|  |  |  |  *           0 for failure. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The return value is 1 on success (*) or 0 in case of error. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * (*) by convention, since the init function must return 1 on success. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-02-07 05:14:03 +08:00
										 |  |  | #  define RUN_ONCE_ALT(once, initalt, init)                               \
 | 
					
						
							| 
									
										
										
										
											2018-11-20 23:32:55 +08:00
										 |  |  |     (CRYPTO_THREAD_run_once(once, initalt##_ossl_) ? init##_ossl_ret_ : 0) | 
					
						
							| 
									
										
										
										
											2019-07-04 17:21:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-07 05:14:03 +08:00
										 |  |  | # endif /* FIPS_MODULE */
 | 
					
						
							|  |  |  | #endif /* OSSL_INTERNAL_THREAD_ONCE_H */
 |