diff options
author | Hugo Landau <hlandau@openssl.org> | 2023-02-21 10:18:58 +0000 |
---|---|---|
committer | Hugo Landau <hlandau@openssl.org> | 2023-03-30 11:14:07 +0100 |
commit | 2b2b26788e7e46abb8fb340d49a088184fbc0b9b (patch) | |
tree | bc8fa45b9ba5caff1cf984ac7a474bfb6d85f7b1 /crypto | |
parent | b21306b9300996b0e69947d6b4cfa64e4c62ec07 (diff) |
threading: Add ossl_crypto_condvar_wait_timeout
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20348)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/thread/arch/thread_posix.c | 25 | ||||
-rw-r--r-- | crypto/thread/arch/thread_win.c | 38 |
2 files changed, 63 insertions, 0 deletions
diff --git a/crypto/thread/arch/thread_posix.c b/crypto/thread/arch/thread_posix.c index b157435fd6..ae79fe579c 100644 --- a/crypto/thread/arch/thread_posix.c +++ b/crypto/thread/arch/thread_posix.c @@ -171,6 +171,31 @@ void ossl_crypto_condvar_wait(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex) pthread_cond_wait(cv_p, mutex_p); } +void ossl_crypto_condvar_wait_timeout(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex, + OSSL_TIME deadline) +{ + pthread_cond_t *cv_p = (pthread_cond_t *)cv; + pthread_mutex_t *mutex_p = (pthread_mutex_t *)mutex; + + if (ossl_time_is_infinite(deadline)) { + /* + * No deadline. Some pthread implementations allow + * pthread_cond_timedwait to work the same as pthread_cond_wait when + * abstime is NULL, but it is unclear whether this is POSIXly correct. + */ + pthread_cond_wait(cv_p, mutex_p); + } else { + struct timespec deadline_ts; + + deadline_ts.tv_sec + = ossl_time2seconds(deadline); + deadline_ts.tv_nsec + = (ossl_time2ticks(deadline) % OSSL_TIME_SECOND) / OSSL_TIME_NS; + + pthread_cond_timedwait(cv_p, mutex_p, &deadline_ts); + } +} + void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR *cv) { pthread_cond_t *cv_p; diff --git a/crypto/thread/arch/thread_win.c b/crypto/thread/arch/thread_win.c index 5bef48458e..38a3e9a75b 100644 --- a/crypto/thread/arch/thread_win.c +++ b/crypto/thread/arch/thread_win.c @@ -162,6 +162,44 @@ void ossl_crypto_condvar_wait(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex) SleepConditionVariableCS(cv_p, mutex_p, INFINITE); } +void ossl_crypto_condvar_wait_timeout(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex, + OSSL_TIME deadline, int *timeout_expired) +{ + DWORD timeout; + CONDITION_VARIABLE *cv_p = (CONDITION_VARIABLE *)cv; + CRITICAL_SECTION *mutex_p = (CRITICAL_SECTION *)mutex; + + if (ossl_time_is_infinite(deadline)) { + timeout = INFINITE; + } else { + OSSL_TIME now = ossl_time_now(); + OSSL_TIME delta = ossl_time_subtract(deadline, now); + uint64_t ms; + + if (ossl_time_is_zero(delta)) { + if (timeout_expired != NULL) + *timeout_expired = 1; + + return; + } + + ms = ossl_time2ms(delta); + + /* + * Amount of time we want to wait is too long for the 32-bit argument to + * the Win32 API, so just wait as long as possible. + */ + if (ms > (uint64_t)(INFINITE - 1)) + timeout = INFINITE - 1; + else + timeout = (DWORD)ms; + } + + if (!SleepConditionVariableCS(cv_p, mutex_p, timeout) + && timeout_expired != NULL) + *timeout_expired = 1; +} + void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR *cv) { CONDITION_VARIABLE *cv_p; |