Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/ssl/quic/quic_thread_assist.c
48261 views
1
/*
2
* Copyright 2023-2025 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
#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"
16
17
#if !defined(OPENSSL_NO_QUIC_THREAD_ASSIST)
18
19
/* Main loop for the QUIC assist thread. */
20
static unsigned int assist_thread_main(void *arg)
21
{
22
QUIC_THREAD_ASSIST *qta = arg;
23
CRYPTO_MUTEX *m = ossl_quic_channel_get_mutex(qta->ch);
24
QUIC_REACTOR *rtor;
25
QUIC_ENGINE *eng = ossl_quic_channel_get0_engine(qta->ch);
26
27
ossl_crypto_mutex_lock(m);
28
29
rtor = ossl_quic_channel_get_reactor(qta->ch);
30
31
for (;;) {
32
OSSL_TIME deadline;
33
34
if (qta->teardown)
35
break;
36
37
deadline = ossl_quic_reactor_get_tick_deadline(rtor);
38
/*
39
* ossl_crypto_condvar_wait_timeout needs to use real time for the
40
* deadline
41
*/
42
deadline = ossl_quic_engine_make_real_time(eng, deadline);
43
ossl_crypto_condvar_wait_timeout(qta->cv, m, deadline);
44
45
/*
46
* We have now been woken up. This can be for one of the following
47
* reasons:
48
*
49
* - We have been asked to teardown (qta->teardown is set);
50
* - The tick deadline has passed.
51
* - The tick deadline has changed.
52
*
53
* For robustness, this loop also handles spurious wakeups correctly
54
* (which does not require any extra code).
55
*/
56
if (qta->teardown)
57
break;
58
59
ossl_quic_reactor_tick(rtor, QUIC_REACTOR_TICK_FLAG_CHANNEL_ONLY);
60
}
61
62
ossl_crypto_mutex_unlock(m);
63
return 1;
64
}
65
66
int ossl_quic_thread_assist_init_start(QUIC_THREAD_ASSIST *qta,
67
QUIC_CHANNEL *ch)
68
{
69
CRYPTO_MUTEX *mutex = ossl_quic_channel_get_mutex(ch);
70
71
if (mutex == NULL)
72
return 0;
73
74
qta->ch = ch;
75
qta->teardown = 0;
76
qta->joined = 0;
77
78
qta->cv = ossl_crypto_condvar_new();
79
if (qta->cv == NULL)
80
return 0;
81
82
qta->t = ossl_crypto_thread_native_start(assist_thread_main,
83
qta, /*joinable=*/1);
84
if (qta->t == NULL) {
85
ossl_crypto_condvar_free(&qta->cv);
86
return 0;
87
}
88
89
return 1;
90
}
91
92
int ossl_quic_thread_assist_stop_async(QUIC_THREAD_ASSIST *qta)
93
{
94
if (!qta->teardown) {
95
qta->teardown = 1;
96
ossl_crypto_condvar_signal(qta->cv);
97
}
98
99
return 1;
100
}
101
102
int ossl_quic_thread_assist_wait_stopped(QUIC_THREAD_ASSIST *qta)
103
{
104
CRYPTO_THREAD_RETVAL rv;
105
CRYPTO_MUTEX *m = ossl_quic_channel_get_mutex(qta->ch);
106
107
if (qta->joined)
108
return 1;
109
110
if (!ossl_quic_thread_assist_stop_async(qta))
111
return 0;
112
113
ossl_crypto_mutex_unlock(m);
114
115
if (!ossl_crypto_thread_native_join(qta->t, &rv)) {
116
ossl_crypto_mutex_lock(m);
117
return 0;
118
}
119
120
qta->joined = 1;
121
122
ossl_crypto_mutex_lock(m);
123
return 1;
124
}
125
126
int ossl_quic_thread_assist_cleanup(QUIC_THREAD_ASSIST *qta)
127
{
128
if (!ossl_assert(qta->joined))
129
return 0;
130
131
ossl_crypto_condvar_free(&qta->cv);
132
ossl_crypto_thread_native_clean(qta->t);
133
134
qta->ch = NULL;
135
qta->t = NULL;
136
return 1;
137
}
138
139
int ossl_quic_thread_assist_notify_deadline_changed(QUIC_THREAD_ASSIST *qta)
140
{
141
if (qta->teardown)
142
return 0;
143
144
ossl_crypto_condvar_signal(qta->cv);
145
return 1;
146
}
147
148
#endif
149
150