diff options
author | Matt Caswell <matt@openssl.org> | 2023-10-06 15:56:15 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2023-10-10 08:17:43 +0100 |
commit | 2b8d81534479b161dda063477272363fb2caef08 (patch) | |
tree | be3113450ccfdebc31a372696dcd635bf929a851 | |
parent | 91895e39b10033178e662fc7427a09d7562cf8e1 (diff) |
When calling ossl_crypto_condvar_wait_timeout() we must use real time
Although many of the QUIC tests use fake time, the time we pass to the
ossl_crypto_condvar_wait_timeout() must be a real time.
Passing fake time was causing the QUIC tserver test to hang because
ossl_crypto_convar_wait_timeout() always timed out immediately and never
relinquished the CPU.
If using fake time we adjust the time to real time just before using it.
Fixes #22020
Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22301)
-rw-r--r-- | include/internal/quic_thread_assist.h | 7 | ||||
-rw-r--r-- | ssl/quic/quic_impl.c | 4 | ||||
-rw-r--r-- | ssl/quic/quic_thread_assist.c | 23 |
3 files changed, 29 insertions, 5 deletions
diff --git a/include/internal/quic_thread_assist.h b/include/internal/quic_thread_assist.h index 7d1b47453a..592c2ffabf 100644 --- a/include/internal/quic_thread_assist.h +++ b/include/internal/quic_thread_assist.h @@ -12,6 +12,7 @@ # include <openssl/ssl.h> # include "internal/thread.h" +# include "internal/time.h" # if defined(OPENSSL_NO_QUIC) || defined(OPENSSL_NO_THREAD_POOL) # define OPENSSL_NO_QUIC_THREAD_ASSIST @@ -46,6 +47,8 @@ typedef struct quic_thread_assist_st { CRYPTO_CONDVAR *cv; CRYPTO_THREAD *t; int teardown, joined; + OSSL_TIME (*now_cb)(void *arg); + void *now_cb_arg; } QUIC_THREAD_ASSIST; /* @@ -55,7 +58,9 @@ typedef struct quic_thread_assist_st { * not affect the state of the mutex. */ int ossl_quic_thread_assist_init_start(QUIC_THREAD_ASSIST *qta, - QUIC_CHANNEL *ch); + QUIC_CHANNEL *ch, + OSSL_TIME (*now_cb)(void *arg), + void *now_cb_arg); /* * Request the thread assist helper to begin stopping the assist thread. This diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index cb927fa52d..86020a450a 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -1532,7 +1532,9 @@ static int ensure_channel_started(QCTX *ctx) #if !defined(OPENSSL_NO_QUIC_THREAD_ASSIST) if (qc->is_thread_assisted) - if (!ossl_quic_thread_assist_init_start(&qc->thread_assist, qc->ch)) { + if (!ossl_quic_thread_assist_init_start(&qc->thread_assist, qc->ch, + qc->override_now_cb, + qc->override_now_cb_arg)) { QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, "failed to start assist thread"); return 0; diff --git a/ssl/quic/quic_thread_assist.c b/ssl/quic/quic_thread_assist.c index b5c1829e8e..e1de72a910 100644 --- a/ssl/quic/quic_thread_assist.c +++ b/ssl/quic/quic_thread_assist.c @@ -28,11 +28,24 @@ static unsigned int assist_thread_main(void *arg) rtor = ossl_quic_channel_get_reactor(qta->ch); for (;;) { + OSSL_TIME deadline; + if (qta->teardown) break; - ossl_crypto_condvar_wait_timeout(qta->cv, m, - ossl_quic_reactor_get_tick_deadline(rtor)); + deadline = ossl_quic_reactor_get_tick_deadline(rtor); + if (qta->now_cb != NULL + && !ossl_time_is_zero(deadline) + && !ossl_time_is_infinite(deadline)) { + /* + * ossl_crypto_condvar_wait_timeout needs to use real time for the + * deadline + */ + deadline = ossl_time_add(ossl_time_subtract(deadline, + qta->now_cb(qta->now_cb_arg)), + ossl_time_now()); + } + ossl_crypto_condvar_wait_timeout(qta->cv, m, deadline); /* * We have now been woken up. This can be for one of the following @@ -56,7 +69,9 @@ static unsigned int assist_thread_main(void *arg) } int ossl_quic_thread_assist_init_start(QUIC_THREAD_ASSIST *qta, - QUIC_CHANNEL *ch) + QUIC_CHANNEL *ch, + OSSL_TIME (*now_cb)(void *arg), + void *now_cb_arg) { CRYPTO_MUTEX *mutex = ossl_quic_channel_get_mutex(ch); @@ -66,6 +81,8 @@ int ossl_quic_thread_assist_init_start(QUIC_THREAD_ASSIST *qta, qta->ch = ch; qta->teardown = 0; qta->joined = 0; + qta->now_cb = now_cb; + qta->now_cb_arg = now_cb_arg; qta->cv = ossl_crypto_condvar_new(); if (qta->cv == NULL) |