2 * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
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
14 #include <openssl/crypto.h>
17 #if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG)
19 typedef unsigned int thread_t
;
21 static int run_thread(thread_t
*t
, void (*f
)(void))
27 static int wait_for_thread(thread_t thread
)
32 #elif defined(OPENSSL_SYS_WINDOWS)
34 typedef HANDLE thread_t
;
36 static DWORD WINAPI
thread_run(LPVOID arg
)
40 *(void **) (&f
) = arg
;
46 static int run_thread(thread_t
*t
, void (*f
)(void))
48 *t
= CreateThread(NULL
, 0, thread_run
, *(void **) &f
, 0, NULL
);
52 static int wait_for_thread(thread_t thread
)
54 return WaitForSingleObject(thread
, INFINITE
) == 0;
59 typedef pthread_t thread_t
;
61 static void *thread_run(void *arg
)
65 *(void **) (&f
) = arg
;
71 static int run_thread(thread_t
*t
, void (*f
)(void))
73 return pthread_create(t
, NULL
, thread_run
, *(void **) &f
) == 0;
76 static int wait_for_thread(thread_t thread
)
78 return pthread_join(thread
, NULL
) == 0;
83 static int test_lock(void)
85 CRYPTO_RWLOCK
*lock
= CRYPTO_THREAD_lock_new();
87 if (!TEST_true(CRYPTO_THREAD_read_lock(lock
))
88 || !TEST_true(CRYPTO_THREAD_unlock(lock
)))
91 CRYPTO_THREAD_lock_free(lock
);
96 static CRYPTO_ONCE once_run
= CRYPTO_ONCE_STATIC_INIT
;
97 static unsigned once_run_count
= 0;
99 static void once_do_run(void)
104 static void once_run_thread_cb(void)
106 CRYPTO_THREAD_run_once(&once_run
, once_do_run
);
109 static int test_once(void)
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))
121 static CRYPTO_THREAD_LOCAL thread_local_key
;
122 static unsigned destructor_run_count
= 0;
123 static int thread_local_thread_cb_ok
= 0;
125 static void thread_local_destructor(void *arg
)
137 static void thread_local_thread_cb(void)
141 ptr
= CRYPTO_THREAD_get_local(&thread_local_key
);
142 if (!TEST_ptr_null(ptr
)
143 || !TEST_true(CRYPTO_THREAD_set_local(&thread_local_key
,
144 &destructor_run_count
)))
147 ptr
= CRYPTO_THREAD_get_local(&thread_local_key
);
148 if (!TEST_ptr_eq(ptr
, &destructor_run_count
))
151 thread_local_thread_cb_ok
= 1;
154 static int test_thread_local(void)
159 if (!TEST_true(CRYPTO_THREAD_init_local(&thread_local_key
,
160 thread_local_destructor
)))
163 ptr
= CRYPTO_THREAD_get_local(&thread_local_key
);
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))
170 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
172 ptr
= CRYPTO_THREAD_get_local(&thread_local_key
);
173 if (!TEST_ptr_null(ptr
))
176 # if !defined(OPENSSL_SYS_WINDOWS)
177 if (!TEST_int_eq(destructor_run_count
, 1))
182 if (!TEST_true(CRYPTO_THREAD_cleanup_local(&thread_local_key
)))
187 int setup_tests(void)
191 ADD_TEST(test_thread_local
);