xref: /src/crypto/openssl/include/internal/thread_arch.h (revision f25b8c9fb4f58cf61adb47d7570abe7caa6d385d)
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