1 /* 2 * Copyright 2019-2024 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_ARCH_H 11 # define OSSL_INTERNAL_THREAD_ARCH_H 12 # include <openssl/configuration.h> 13 # include <openssl/e_os2.h> 14 # include "internal/time.h" 15 16 # if defined(_WIN32) 17 # include <windows.h> 18 # endif 19 20 # if defined(OPENSSL_THREADS) && defined(OPENSSL_SYS_UNIX) 21 # define OPENSSL_THREADS_POSIX 22 # elif defined(OPENSSL_THREADS) && defined(OPENSSL_SYS_VMS) 23 # define OPENSSL_THREADS_POSIX 24 # elif defined(OPENSSL_THREADS) && defined(OPENSSL_SYS_WINDOWS) && \ 25 defined(_WIN32_WINNT) 26 # if _WIN32_WINNT >= 0x0600 27 # define OPENSSL_THREADS_WINNT 28 # elif _WIN32_WINNT >= 0x0501 29 # define OPENSSL_THREADS_WINNT 30 # define OPENSSL_THREADS_WINNT_LEGACY 31 # else 32 # define OPENSSL_THREADS_NONE 33 # endif 34 # else 35 # define OPENSSL_THREADS_NONE 36 # endif 37 38 # include <openssl/crypto.h> 39 40 typedef struct crypto_mutex_st CRYPTO_MUTEX; 41 typedef struct crypto_condvar_st CRYPTO_CONDVAR; 42 43 CRYPTO_MUTEX *ossl_crypto_mutex_new(void); 44 void ossl_crypto_mutex_lock(CRYPTO_MUTEX *mutex); 45 int ossl_crypto_mutex_try_lock(CRYPTO_MUTEX *mutex); 46 void ossl_crypto_mutex_unlock(CRYPTO_MUTEX *mutex); 47 void ossl_crypto_mutex_free(CRYPTO_MUTEX **mutex); 48 49 CRYPTO_CONDVAR *ossl_crypto_condvar_new(void); 50 void ossl_crypto_condvar_wait(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex); 51 void ossl_crypto_condvar_wait_timeout(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex, 52 OSSL_TIME deadline); 53 void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR *cv); 54 void ossl_crypto_condvar_signal(CRYPTO_CONDVAR *cv); 55 void ossl_crypto_condvar_free(CRYPTO_CONDVAR **cv); 56 57 typedef uint32_t CRYPTO_THREAD_RETVAL; 58 typedef CRYPTO_THREAD_RETVAL (*CRYPTO_THREAD_ROUTINE)(void *); 59 typedef CRYPTO_THREAD_RETVAL (*CRYPTO_THREAD_ROUTINE_CB)(void *, 60 void (**)(void *), 61 void **); 62 63 # define CRYPTO_THREAD_NO_STATE 0UL 64 # define CRYPTO_THREAD_FINISHED (1UL << 0) 65 # define CRYPTO_THREAD_JOIN_AWAIT (1UL << 1) 66 # define CRYPTO_THREAD_JOINED (1UL << 2) 67 68 # define CRYPTO_THREAD_GET_STATE(THREAD, FLAG) ((THREAD)->state & (FLAG)) 69 # define CRYPTO_THREAD_GET_ERROR(THREAD, FLAG) (((THREAD)->state >> 16) & (FLAG)) 70 71 typedef struct crypto_thread_st { 72 uint32_t state; 73 void *data; 74 CRYPTO_THREAD_ROUTINE routine; 75 CRYPTO_THREAD_RETVAL retval; 76 void *handle; 77 CRYPTO_MUTEX *lock; 78 CRYPTO_MUTEX *statelock; 79 CRYPTO_CONDVAR *condvar; 80 unsigned long thread_id; 81 int joinable; 82 OSSL_LIB_CTX *ctx; 83 } CRYPTO_THREAD; 84 85 # if defined(OPENSSL_THREADS) 86 87 # define CRYPTO_THREAD_UNSET_STATE(THREAD, FLAG) \ 88 do { \ 89 (THREAD)->state &= ~(FLAG); \ 90 } while ((void)0, 0) 91 92 # define CRYPTO_THREAD_SET_STATE(THREAD, FLAG) \ 93 do { \ 94 (THREAD)->state |= (FLAG); \ 95 } while ((void)0, 0) 96 97 # define CRYPTO_THREAD_SET_ERROR(THREAD, FLAG) \ 98 do { \ 99 (THREAD)->state |= ((FLAG) << 16); \ 100 } while ((void)0, 0) 101 102 # define CRYPTO_THREAD_UNSET_ERROR(THREAD, FLAG) \ 103 do { \ 104 (THREAD)->state &= ~((FLAG) << 16); \ 105 } while ((void)0, 0) 106 107 # else 108 109 # define CRYPTO_THREAD_UNSET_STATE(THREAD, FLAG) 110 # define CRYPTO_THREAD_SET_STATE(THREAD, FLAG) 111 # define CRYPTO_THREAD_SET_ERROR(THREAD, FLAG) 112 # define CRYPTO_THREAD_UNSET_ERROR(THREAD, FLAG) 113 114 # endif /* defined(OPENSSL_THREADS) */ 115 116 CRYPTO_THREAD * ossl_crypto_thread_native_start(CRYPTO_THREAD_ROUTINE routine, 117 void *data, int joinable); 118 int ossl_crypto_thread_native_spawn(CRYPTO_THREAD *thread); 119 int ossl_crypto_thread_native_join(CRYPTO_THREAD *thread, 120 CRYPTO_THREAD_RETVAL *retval); 121 int ossl_crypto_thread_native_perform_join(CRYPTO_THREAD *thread, 122 CRYPTO_THREAD_RETVAL *retval); 123 int ossl_crypto_thread_native_exit(void); 124 int ossl_crypto_thread_native_is_self(CRYPTO_THREAD *thread); 125 int ossl_crypto_thread_native_clean(CRYPTO_THREAD *thread); 126 127 #endif /* OSSL_INTERNAL_THREAD_ARCH_H */ 128