Coverage Report

Created: 2023-06-08 06:40

/src/openssl111/crypto/threads_pthread.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2016-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
#include "internal/cryptlib.h"
12
13
#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && !defined(OPENSSL_SYS_WINDOWS)
14
15
# if defined(OPENSSL_SYS_UNIX)
16
#  include <sys/types.h>
17
#  include <unistd.h>
18
#endif
19
20
# ifdef PTHREAD_RWLOCK_INITIALIZER
21
#  define USE_RWLOCK
22
# endif
23
24
CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
25
4
{
26
4
# ifdef USE_RWLOCK
27
4
    CRYPTO_RWLOCK *lock;
28
29
4
    if ((lock = OPENSSL_zalloc(sizeof(pthread_rwlock_t))) == NULL) {
30
        /* Don't set error, to avoid recursion blowup. */
31
0
        return NULL;
32
0
    }
33
34
4
    if (pthread_rwlock_init(lock, NULL) != 0) {
35
0
        OPENSSL_free(lock);
36
0
        return NULL;
37
0
    }
38
# else
39
    pthread_mutexattr_t attr;
40
    CRYPTO_RWLOCK *lock;
41
42
    if ((lock = OPENSSL_zalloc(sizeof(pthread_mutex_t))) == NULL) {
43
        /* Don't set error, to avoid recursion blowup. */
44
        return NULL;
45
    }
46
47
    pthread_mutexattr_init(&attr);
48
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
49
50
    if (pthread_mutex_init(lock, &attr) != 0) {
51
        pthread_mutexattr_destroy(&attr);
52
        OPENSSL_free(lock);
53
        return NULL;
54
    }
55
56
    pthread_mutexattr_destroy(&attr);
57
# endif
58
59
4
    return lock;
60
4
}
61
62
int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
63
58
{
64
58
# ifdef USE_RWLOCK
65
58
    if (pthread_rwlock_rdlock(lock) != 0)
66
0
        return 0;
67
# else
68
    if (pthread_mutex_lock(lock) != 0)
69
        return 0;
70
# endif
71
72
58
    return 1;
73
58
}
74
75
int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
76
590
{
77
590
# ifdef USE_RWLOCK
78
590
    if (pthread_rwlock_wrlock(lock) != 0)
79
0
        return 0;
80
# else
81
    if (pthread_mutex_lock(lock) != 0)
82
        return 0;
83
# endif
84
85
590
    return 1;
86
590
}
87
88
int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock)
89
648
{
90
648
# ifdef USE_RWLOCK
91
648
    if (pthread_rwlock_unlock(lock) != 0)
92
0
        return 0;
93
# else
94
    if (pthread_mutex_unlock(lock) != 0)
95
        return 0;
96
# endif
97
98
648
    return 1;
99
648
}
100
101
void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock)
102
16
{
103
16
    if (lock == NULL)
104
12
        return;
105
106
4
# ifdef USE_RWLOCK
107
4
    pthread_rwlock_destroy(lock);
108
# else
109
    pthread_mutex_destroy(lock);
110
# endif
111
4
    OPENSSL_free(lock);
112
113
4
    return;
114
16
}
115
116
int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
117
6.86k
{
118
6.86k
    if (pthread_once(once, init) != 0)
119
0
        return 0;
120
121
6.86k
    return 1;
122
6.86k
}
123
124
int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
125
4
{
126
4
    if (pthread_key_create(key, cleanup) != 0)
127
0
        return 0;
128
129
4
    return 1;
130
4
}
131
132
void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key)
133
3.33k
{
134
3.33k
    return pthread_getspecific(*key);
135
3.33k
}
136
137
int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val)
138
10
{
139
10
    if (pthread_setspecific(*key, val) != 0)
140
0
        return 0;
141
142
10
    return 1;
143
10
}
144
145
int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key)
146
4
{
147
4
    if (pthread_key_delete(*key) != 0)
148
0
        return 0;
149
150
4
    return 1;
151
4
}
152
153
CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void)
154
0
{
155
0
    return pthread_self();
156
0
}
157
158
int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b)
159
0
{
160
0
    return pthread_equal(a, b);
161
0
}
162
163
int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
164
0
{
165
0
# if defined(__GNUC__) && defined(__ATOMIC_ACQ_REL)
166
0
    if (__atomic_is_lock_free(sizeof(*val), val)) {
167
0
        *ret = __atomic_add_fetch(val, amount, __ATOMIC_ACQ_REL);
168
0
        return 1;
169
0
    }
170
0
# endif
171
0
    if (!CRYPTO_THREAD_write_lock(lock))
172
0
        return 0;
173
174
0
    *val += amount;
175
0
    *ret  = *val;
176
177
0
    if (!CRYPTO_THREAD_unlock(lock))
178
0
        return 0;
179
180
0
    return 1;
181
0
}
182
183
# ifdef OPENSSL_SYS_UNIX
184
static pthread_once_t fork_once_control = PTHREAD_ONCE_INIT;
185
186
static void fork_once_func(void)
187
0
{
188
0
    pthread_atfork(OPENSSL_fork_prepare,
189
0
                   OPENSSL_fork_parent, OPENSSL_fork_child);
190
0
}
191
# endif
192
193
int openssl_init_fork_handlers(void)
194
0
{
195
0
# ifdef OPENSSL_SYS_UNIX
196
0
    if (pthread_once(&fork_once_control, fork_once_func) == 0)
197
0
        return 1;
198
0
# endif
199
0
    return 0;
200
0
}
201
202
int openssl_get_fork_id(void)
203
0
{
204
0
    return getpid();
205
0
}
206
#endif