2 * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
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
10 #include <openssl/macros.h>
11 #include "quic_local.h"
12 #include "internal/time.h"
13 #include "internal/thread.h"
14 #include "internal/thread_arch.h"
15 #include "internal/quic_thread_assist.h"
17 #if !defined(OPENSSL_NO_QUIC) && !defined(OPENSSL_NO_THREAD_POOL)
19 /* Main loop for the QUIC assist thread. */
20 static unsigned int assist_thread_main(void *arg)
22 QUIC_THREAD_ASSIST *qta = arg;
23 CRYPTO_MUTEX *m = ossl_quic_channel_get_mutex(qta->ch);
26 ossl_crypto_mutex_lock(m);
28 rtor = ossl_quic_channel_get_reactor(qta->ch);
34 ossl_crypto_condvar_wait_timeout(qta->cv, m,
35 ossl_quic_reactor_get_tick_deadline(rtor));
38 * We have now been woken up. This can be for one of the following
41 * - We have been asked to teardown (qta->teardown is set);
42 * - The tick deadline has passed.
43 * - The tick deadline has changed.
45 * For robustness, this loop also handles spurious wakeups correctly
46 * (which does not require any extra code).
51 ossl_quic_reactor_tick(rtor, QUIC_REACTOR_TICK_FLAG_CHANNEL_ONLY);
54 ossl_crypto_mutex_unlock(m);
58 int ossl_quic_thread_assist_init_start(QUIC_THREAD_ASSIST *qta,
61 CRYPTO_MUTEX *mutex = ossl_quic_channel_get_mutex(ch);
70 qta->cv = ossl_crypto_condvar_new();
74 qta->t = ossl_crypto_thread_native_start(assist_thread_main,
77 ossl_crypto_condvar_free(qta->cv);
84 int ossl_quic_thread_assist_stop_async(QUIC_THREAD_ASSIST *qta)
88 ossl_crypto_condvar_signal(qta->cv);
94 int ossl_quic_thread_assist_wait_stopped(QUIC_THREAD_ASSIST *qta)
96 CRYPTO_THREAD_RETVAL rv;
97 CRYPTO_MUTEX *m = ossl_quic_channel_get_mutex(qta->ch);
102 if (!ossl_quic_thread_assist_stop_async(qta))
105 ossl_crypto_mutex_unlock(m);
107 if (!ossl_crypto_thread_native_join(qta->t, &rv)) {
108 ossl_crypto_mutex_lock(m);
114 ossl_crypto_mutex_lock(m);
118 int ossl_quic_thread_assist_cleanup(QUIC_THREAD_ASSIST *qta)
120 if (!ossl_assert(qta->joined))
123 ossl_crypto_condvar_free(&qta->cv);
124 ossl_crypto_thread_native_clean(qta->t);
131 int ossl_quic_thread_assist_notify_deadline_changed(QUIC_THREAD_ASSIST *qta)
136 ossl_crypto_condvar_signal(qta->cv);