Raise an error on syscall failure in tls_retry_write_records
[openssl.git] / include / internal / thread_once.h
1 /*
2  * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (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 #ifndef OSSL_INTERNAL_THREAD_ONCE_H
11 # define OSSL_INTERNAL_THREAD_ONCE_H
12 # pragma once
13
14 # include <openssl/crypto.h>
15
16 /*
17  * Initialisation of global data should never happen via "RUN_ONCE" inside the
18  * FIPS module. Global data should instead always be associated with a specific
19  * OSSL_LIB_CTX object. In this way data will get cleaned up correctly when the
20  * module gets unloaded.
21  */
22 # if !defined(FIPS_MODULE) || defined(ALLOW_RUN_ONCE_IN_FIPS)
23 /*
24  * DEFINE_RUN_ONCE: Define an initialiser function that should be run exactly
25  * once. It takes no arguments and returns an int result (1 for success or
26  * 0 for failure). Typical usage might be:
27  *
28  * DEFINE_RUN_ONCE(myinitfunc)
29  * {
30  *     do_some_initialisation();
31  *     if (init_is_successful())
32  *         return 1;
33  *
34  *     return 0;
35  * }
36  */
37 #  define DEFINE_RUN_ONCE(init)                   \
38     static int init(void);                     \
39     int init##_ossl_ret_ = 0;                   \
40     void init##_ossl_(void)                     \
41     {                                           \
42         init##_ossl_ret_ = init();              \
43     }                                           \
44     static int init(void)
45
46 /*
47  * DECLARE_RUN_ONCE: Declare an initialiser function that should be run exactly
48  * once that has been defined in another file via DEFINE_RUN_ONCE().
49  */
50 #  define DECLARE_RUN_ONCE(init)                  \
51     extern int init##_ossl_ret_;                \
52     void init##_ossl_(void);
53
54 /*
55  * DEFINE_RUN_ONCE_STATIC: Define an initialiser function that should be run
56  * exactly once. This function will be declared as static within the file. It
57  * takes no arguments and returns an int result (1 for success or 0 for
58  * failure). Typical usage might be:
59  *
60  * DEFINE_RUN_ONCE_STATIC(myinitfunc)
61  * {
62  *     do_some_initialisation();
63  *     if (init_is_successful())
64  *         return 1;
65  *
66  *     return 0;
67  * }
68  */
69 #  define DEFINE_RUN_ONCE_STATIC(init)            \
70     static int init(void);                     \
71     static int init##_ossl_ret_ = 0;            \
72     static void init##_ossl_(void)              \
73     {                                           \
74         init##_ossl_ret_ = init();              \
75     }                                           \
76     static int init(void)
77
78 /*
79  * DEFINE_RUN_ONCE_STATIC_ALT: Define an alternative initialiser function. This
80  * function will be declared as static within the file. It takes no arguments
81  * and returns an int result (1 for success or 0 for failure). An alternative
82  * initialiser function is expected to be associated with a primary initialiser
83  * function defined via DEFINE_ONCE_STATIC where both functions use the same
84  * CRYPTO_ONCE object to synchronise. Where an alternative initialiser function
85  * is used only one of the primary or the alternative initialiser function will
86  * ever be called - and that function will be called exactly once. Definition
87  * of an alternative initialiser function MUST occur AFTER the definition of the
88  * primary initialiser function.
89  *
90  * Typical usage might be:
91  *
92  * DEFINE_RUN_ONCE_STATIC(myinitfunc)
93  * {
94  *     do_some_initialisation();
95  *     if (init_is_successful())
96  *         return 1;
97  *
98  *     return 0;
99  * }
100  *
101  * DEFINE_RUN_ONCE_STATIC_ALT(myaltinitfunc, myinitfunc)
102  * {
103  *     do_some_alternative_initialisation();
104  *     if (init_is_successful())
105  *         return 1;
106  *
107  *     return 0;
108  * }
109  */
110 #  define DEFINE_RUN_ONCE_STATIC_ALT(initalt, init) \
111     static int initalt(void);                     \
112     static void initalt##_ossl_(void)             \
113     {                                             \
114         init##_ossl_ret_ = initalt();             \
115     }                                             \
116     static int initalt(void)
117
118 /*
119  * RUN_ONCE - use CRYPTO_THREAD_run_once, and check if the init succeeded
120  * @once: pointer to static object of type CRYPTO_ONCE
121  * @init: function name that was previously given to DEFINE_RUN_ONCE,
122  *        DEFINE_RUN_ONCE_STATIC or DECLARE_RUN_ONCE.  This function
123  *        must return 1 for success or 0 for failure.
124  *
125  * The return value is 1 on success (*) or 0 in case of error.
126  *
127  * (*) by convention, since the init function must return 1 on success.
128  */
129 #  define RUN_ONCE(once, init)                                            \
130     (CRYPTO_THREAD_run_once(once, init##_ossl_) ? init##_ossl_ret_ : 0)
131
132 /*
133  * RUN_ONCE_ALT - use CRYPTO_THREAD_run_once, to run an alternative initialiser
134  *                function and check if that initialisation succeeded
135  * @once:    pointer to static object of type CRYPTO_ONCE
136  * @initalt: alternative initialiser function name that was previously given to
137  *           DEFINE_RUN_ONCE_STATIC_ALT.  This function must return 1 for
138  *           success or 0 for failure.
139  * @init:    primary initialiser function name that was previously given to
140  *           DEFINE_RUN_ONCE_STATIC.  This function must return 1 for success or
141  *           0 for failure.
142  *
143  * The return value is 1 on success (*) or 0 in case of error.
144  *
145  * (*) by convention, since the init function must return 1 on success.
146  */
147 #  define RUN_ONCE_ALT(once, initalt, init)                               \
148     (CRYPTO_THREAD_run_once(once, initalt##_ossl_) ? init##_ossl_ret_ : 0)
149
150 # endif /* FIPS_MODULE */
151 #endif /* OSSL_INTERNAL_THREAD_ONCE_H */