Home | History | Annotate | Line # | Download | only in internal
      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