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