1 /* 2 * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <openssl/crypto.h> 11 12 /* 13 * DEFINE_RUN_ONCE: Define an initialiser function that should be run exactly 14 * once. It takes no arguments and returns and int result (1 for success or 15 * 0 for failure). Typical usage might be: 16 * 17 * DEFINE_RUN_ONCE(myinitfunc) 18 * { 19 * do_some_initialisation(); 20 * if (init_is_successful()) 21 * return 1; 22 * 23 * return 0; 24 * } 25 */ 26 #define DEFINE_RUN_ONCE(init) \ 27 static int init(void); \ 28 int init##_ossl_ret_ = 0; \ 29 void init##_ossl_(void) \ 30 { \ 31 init##_ossl_ret_ = init(); \ 32 } \ 33 static int init(void) 34 35 /* 36 * DECLARE_RUN_ONCE: Declare an initialiser function that should be run exactly 37 * once that has been defined in another file via DEFINE_RUN_ONCE(). 38 */ 39 #define DECLARE_RUN_ONCE(init) \ 40 extern int init##_ossl_ret_; \ 41 void init##_ossl_(void); 42 43 /* 44 * DEFINE_RUN_ONCE_STATIC: Define an initialiser function that should be run 45 * exactly once. This function will be declared as static within the file. It 46 * takes no arguments and returns and int result (1 for success or 0 for 47 * failure). Typical usage might be: 48 * 49 * DEFINE_RUN_ONCE_STATIC(myinitfunc) 50 * { 51 * do_some_initialisation(); 52 * if (init_is_successful()) 53 * return 1; 54 * 55 * return 0; 56 * } 57 */ 58 #define DEFINE_RUN_ONCE_STATIC(init) \ 59 static int init(void); \ 60 static int init##_ossl_ret_ = 0; \ 61 static void init##_ossl_(void) \ 62 { \ 63 init##_ossl_ret_ = init(); \ 64 } \ 65 static int init(void) 66 67 /* 68 * DEFINE_RUN_ONCE_STATIC_ALT: Define an alternative initialiser function. This 69 * function will be declared as static within the file. It takes no arguments 70 * and returns an int result (1 for success or 0 for failure). An alternative 71 * initialiser function is expected to be associated with a primary initialiser 72 * function defined via DEFINE_ONCE_STATIC where both functions use the same 73 * CRYPTO_ONCE object to synchronise. Where an alternative initialiser function 74 * is used only one of the primary or the alternative initialiser function will 75 * ever be called - and that function will be called exactly once. Definitition 76 * of an alternative initialiser function MUST occur AFTER the definition of the 77 * primary initialiser function. 78 * 79 * Typical usage might be: 80 * 81 * DEFINE_RUN_ONCE_STATIC(myinitfunc) 82 * { 83 * do_some_initialisation(); 84 * if (init_is_successful()) 85 * return 1; 86 * 87 * return 0; 88 * } 89 * 90 * DEFINE_RUN_ONCE_STATIC_ALT(myaltinitfunc, myinitfunc) 91 * { 92 * do_some_alternative_initialisation(); 93 * if (init_is_successful()) 94 * return 1; 95 * 96 * return 0; 97 * } 98 */ 99 #define DEFINE_RUN_ONCE_STATIC_ALT(initalt, init) \ 100 static int initalt(void); \ 101 static void initalt##_ossl_(void) \ 102 { \ 103 init##_ossl_ret_ = initalt(); \ 104 } \ 105 static int initalt(void) 106 107 /* 108 * RUN_ONCE - use CRYPTO_THREAD_run_once, and check if the init succeeded 109 * @once: pointer to static object of type CRYPTO_ONCE 110 * @init: function name that was previously given to DEFINE_RUN_ONCE, 111 * DEFINE_RUN_ONCE_STATIC or DECLARE_RUN_ONCE. This function 112 * must return 1 for success or 0 for failure. 113 * 114 * The return value is 1 on success (*) or 0 in case of error. 115 * 116 * (*) by convention, since the init function must return 1 on success. 117 */ 118 #define RUN_ONCE(once, init) \ 119 (CRYPTO_THREAD_run_once(once, init##_ossl_) ? init##_ossl_ret_ : 0) 120 121 /* 122 * RUN_ONCE_ALT - use CRYPTO_THREAD_run_once, to run an alternative initialiser 123 * function and check if that initialisation succeeded 124 * @once: pointer to static object of type CRYPTO_ONCE 125 * @initalt: alternative initialiser function name that was previously given to 126 * DEFINE_RUN_ONCE_STATIC_ALT. This function must return 1 for 127 * success or 0 for failure. 128 * @init: primary initialiser function name that was previously given to 129 * DEFINE_RUN_ONCE_STATIC. This function must return 1 for success or 130 * 0 for failure. 131 * 132 * The return value is 1 on success (*) or 0 in case of error. 133 * 134 * (*) by convention, since the init function must return 1 on success. 135 */ 136 #define RUN_ONCE_ALT(once, initalt, init) \ 137 (CRYPTO_THREAD_run_once(once, initalt##_ossl_) ? init##_ossl_ret_ : 0) 138