summaryrefslogtreecommitdiff
path: root/crypto/thread
diff options
context:
space:
mode:
authorHugo Landau <hlandau@openssl.org>2023-02-21 10:18:58 +0000
committerHugo Landau <hlandau@openssl.org>2023-03-30 11:14:07 +0100
commit2b2b26788e7e46abb8fb340d49a088184fbc0b9b (patch)
treebc8fa45b9ba5caff1cf984ac7a474bfb6d85f7b1 /crypto/thread
parentb21306b9300996b0e69947d6b4cfa64e4c62ec07 (diff)
downloadopenssl-new-2b2b26788e7e46abb8fb340d49a088184fbc0b9b.tar.gz
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/thread')
-rw-r--r--crypto/thread/arch/thread_posix.c25
-rw-r--r--crypto/thread/arch/thread_win.c38
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;