Coverage Report

Created: 2025-06-13 06:55

/src/openssl/include/internal/thread_once.h
Line
Count
Source (jump to first uncovered line)
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
1
    {                                           \
42
1
        init##_ossl_ret_ = init();              \
43
1
    }                                           \
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
15
    {                                           \
74
15
        init##_ossl_ret_ = init();              \
75
15
    }                                           \
init.c:ossl_init_base_ossl_
Line
Count
Source
73
1
    {                                           \
74
1
        init##_ossl_ret_ = init();              \
75
1
    }                                           \
init.c:ossl_init_register_atexit_ossl_
Line
Count
Source
73
1
    {                                           \
74
1
        init##_ossl_ret_ = init();              \
75
1
    }                                           \
init.c:ossl_init_load_crypto_nodelete_ossl_
Line
Count
Source
73
1
    {                                           \
74
1
        init##_ossl_ret_ = init();              \
75
1
    }                                           \
init.c:ossl_init_load_crypto_strings_ossl_
Line
Count
Source
73
1
    {                                           \
74
1
        init##_ossl_ret_ = init();              \
75
1
    }                                           \
Unexecuted instantiation: init.c:ossl_init_load_ssl_strings_ossl_
init.c:ossl_init_add_all_ciphers_ossl_
Line
Count
Source
73
1
    {                                           \
74
1
        init##_ossl_ret_ = init();              \
75
1
    }                                           \
init.c:ossl_init_add_all_digests_ossl_
Line
Count
Source
73
1
    {                                           \
74
1
        init##_ossl_ret_ = init();              \
75
1
    }                                           \
init.c:ossl_init_config_ossl_
Line
Count
Source
73
1
    {                                           \
74
1
        init##_ossl_ret_ = init();              \
75
1
    }                                           \
Unexecuted instantiation: init.c:ossl_init_async_ossl_
Unexecuted instantiation: init.c:ossl_init_engine_openssl_ossl_
Unexecuted instantiation: init.c:ossl_init_engine_rdrand_ossl_
Unexecuted instantiation: init.c:ossl_init_engine_dynamic_ossl_
Unexecuted instantiation: init.c:ossl_init_engine_padlock_ossl_
Unexecuted instantiation: init.c:ossl_init_engine_afalg_ossl_
initthread.c:create_global_tevent_register_ossl_
Line
Count
Source
73
1
    {                                           \
74
1
        init##_ossl_ret_ = init();              \
75
1
    }                                           \
o_names.c:o_names_init_ossl_
Line
Count
Source
73
1
    {                                           \
74
1
        init##_ossl_ret_ = init();              \
75
1
    }                                           \
obj_dat.c:obj_lock_initialise_ossl_
Line
Count
Source
73
1
    {                                           \
74
1
        init##_ossl_ret_ = init();              \
75
1
    }                                           \
Unexecuted instantiation: obj_xref.c:o_sig_init_ossl_
rand_lib.c:do_rand_init_ossl_
Line
Count
Source
73
1
    {                                           \
74
1
        init##_ossl_ret_ = init();              \
75
1
    }                                           \
Unexecuted instantiation: store_register.c:do_registry_init_ossl_
Unexecuted instantiation: bio_meth.c:do_bio_type_init_ossl_
Unexecuted instantiation: conf_mod.c:do_load_builtin_modules_ossl_
conf_mod.c:do_init_module_list_lock_ossl_
Line
Count
Source
73
1
    {                                           \
74
1
        init##_ossl_ret_ = init();              \
75
1
    }                                           \
err.c:do_err_strings_init_ossl_
Line
Count
Source
73
1
    {                                           \
74
1
        init##_ossl_ret_ = init();              \
75
1
    }                                           \
err.c:err_do_init_ossl_
Line
Count
Source
73
1
    {                                           \
74
1
        init##_ossl_ret_ = init();              \
75
1
    }                                           \
context.c:default_context_do_init_ossl_
Line
Count
Source
73
1
    {                                           \
74
1
        init##_ossl_ret_ = init();              \
75
1
    }                                           \
Unexecuted instantiation: ui_util.c:ui_method_data_index_init_ossl_
Unexecuted instantiation: bio_addr.c:do_bio_lookup_init_ossl_
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
0
    {                                             \
114
0
        init##_ossl_ret_ = initalt();             \
115
0
    }                                             \
Unexecuted instantiation: init.c:ossl_init_no_register_atexit_ossl_
Unexecuted instantiation: init.c:ossl_init_no_load_crypto_strings_ossl_
Unexecuted instantiation: init.c:ossl_init_no_load_ssl_strings_ossl_
Unexecuted instantiation: init.c:ossl_init_no_add_all_ciphers_ossl_
Unexecuted instantiation: init.c:ossl_init_no_add_all_digests_ossl_
Unexecuted instantiation: init.c:ossl_init_no_config_ossl_
Unexecuted instantiation: init.c:ossl_init_config_settings_ossl_
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
12.9k
    (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
0
    (CRYPTO_THREAD_run_once(once, initalt##_ossl_) ? init##_ossl_ret_ : 0)
149
150
# endif /* FIPS_MODULE */
151
#endif /* OSSL_INTERNAL_THREAD_ONCE_H */