]> git.ipfire.org Git - thirdparty/openssl.git/blame - test/threadstest.c
Make sure we use the libctx when creating an EVP_PKEY_CTX in libssl
[thirdparty/openssl.git] / test / threadstest.c
CommitLineData
440e5d80 1/*
ee25dd45 2 * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
71a04cfc 3 *
909f1a2e 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
440e5d80
RS
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
71a04cfc
AG
8 */
9
f1f5ee17
AP
10#if defined(_WIN32)
11# include <windows.h>
12#endif
13
71a04cfc 14#include <openssl/crypto.h>
ee25dd45 15#include "testutil.h"
71a04cfc
AG
16
17#if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG)
18
19typedef unsigned int thread_t;
20
21static int run_thread(thread_t *t, void (*f)(void))
22{
23 f();
24 return 1;
25}
26
27static int wait_for_thread(thread_t thread)
28{
29 return 1;
30}
31
32#elif defined(OPENSSL_SYS_WINDOWS)
33
34typedef HANDLE thread_t;
35
36static DWORD WINAPI thread_run(LPVOID arg)
37{
38 void (*f)(void);
39
40 *(void **) (&f) = arg;
41
42 f();
43 return 0;
44}
45
46static int run_thread(thread_t *t, void (*f)(void))
47{
48 *t = CreateThread(NULL, 0, thread_run, *(void **) &f, 0, NULL);
49 return *t != NULL;
50}
51
52static int wait_for_thread(thread_t thread)
53{
54 return WaitForSingleObject(thread, INFINITE) == 0;
55}
56
57#else
58
59typedef pthread_t thread_t;
60
61static void *thread_run(void *arg)
62{
63 void (*f)(void);
64
65 *(void **) (&f) = arg;
66
67 f();
68 return NULL;
69}
70
71static int run_thread(thread_t *t, void (*f)(void))
72{
73 return pthread_create(t, NULL, thread_run, *(void **) &f) == 0;
74}
75
76static int wait_for_thread(thread_t thread)
77{
78 return pthread_join(thread, NULL) == 0;
79}
80
81#endif
82
83static int test_lock(void)
84{
85 CRYPTO_RWLOCK *lock = CRYPTO_THREAD_lock_new();
86
ee25dd45
P
87 if (!TEST_true(CRYPTO_THREAD_read_lock(lock))
88 || !TEST_true(CRYPTO_THREAD_unlock(lock)))
71a04cfc 89 return 0;
71a04cfc
AG
90
91 CRYPTO_THREAD_lock_free(lock);
92
93 return 1;
94}
95
96static CRYPTO_ONCE once_run = CRYPTO_ONCE_STATIC_INIT;
97static unsigned once_run_count = 0;
98
99static void once_do_run(void)
100{
101 once_run_count++;
102}
103
104static void once_run_thread_cb(void)
105{
106 CRYPTO_THREAD_run_once(&once_run, once_do_run);
107}
108
109static int test_once(void)
110{
111 thread_t thread;
71a04cfc 112
ee25dd45
P
113 if (!TEST_true(run_thread(&thread, once_run_thread_cb))
114 || !TEST_true(wait_for_thread(thread))
115 || !CRYPTO_THREAD_run_once(&once_run, once_do_run)
116 || !TEST_int_eq(once_run_count, 1))
71a04cfc 117 return 0;
71a04cfc
AG
118 return 1;
119}
120
121static CRYPTO_THREAD_LOCAL thread_local_key;
122static unsigned destructor_run_count = 0;
123static int thread_local_thread_cb_ok = 0;
124
125static void thread_local_destructor(void *arg)
126{
127 unsigned *count;
128
129 if (arg == NULL)
130 return;
131
132 count = arg;
133
134 (*count)++;
135}
136
137static void thread_local_thread_cb(void)
138{
139 void *ptr;
140
141 ptr = CRYPTO_THREAD_get_local(&thread_local_key);
ee25dd45
P
142 if (!TEST_ptr_null(ptr)
143 || !TEST_true(CRYPTO_THREAD_set_local(&thread_local_key,
144 &destructor_run_count)))
71a04cfc 145 return;
71a04cfc
AG
146
147 ptr = CRYPTO_THREAD_get_local(&thread_local_key);
ee25dd45 148 if (!TEST_ptr_eq(ptr, &destructor_run_count))
71a04cfc 149 return;
71a04cfc
AG
150
151 thread_local_thread_cb_ok = 1;
152}
153
154static int test_thread_local(void)
155{
156 thread_t thread;
157 void *ptr = NULL;
158
ee25dd45
P
159 if (!TEST_true(CRYPTO_THREAD_init_local(&thread_local_key,
160 thread_local_destructor)))
71a04cfc 161 return 0;
71a04cfc
AG
162
163 ptr = CRYPTO_THREAD_get_local(&thread_local_key);
ee25dd45
P
164 if (!TEST_ptr_null(ptr)
165 || !TEST_true(run_thread(&thread, thread_local_thread_cb))
166 || !TEST_true(wait_for_thread(thread))
167 || !TEST_int_eq(thread_local_thread_cb_ok, 1))
71a04cfc 168 return 0;
71a04cfc
AG
169
170#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
171
172 ptr = CRYPTO_THREAD_get_local(&thread_local_key);
ee25dd45 173 if (!TEST_ptr_null(ptr))
71a04cfc 174 return 0;
71a04cfc
AG
175
176# if !defined(OPENSSL_SYS_WINDOWS)
ee25dd45 177 if (!TEST_int_eq(destructor_run_count, 1))
71a04cfc 178 return 0;
71a04cfc 179# endif
71a04cfc
AG
180#endif
181
ee25dd45 182 if (!TEST_true(CRYPTO_THREAD_cleanup_local(&thread_local_key)))
71a04cfc 183 return 0;
71a04cfc
AG
184 return 1;
185}
186
ad887416 187int setup_tests(void)
71a04cfc 188{
ee25dd45
P
189 ADD_TEST(test_lock);
190 ADD_TEST(test_once);
191 ADD_TEST(test_thread_local);
ad887416 192 return 1;
71a04cfc 193}