QUIC Thread Assisted Mode: Support Windows XP

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20348)
This commit is contained in:
Hugo Landau 2023-02-22 19:15:16 +00:00
parent 99ed85bba9
commit 1dd04a0fe2
7 changed files with 137 additions and 37 deletions

View File

@ -110,6 +110,7 @@ SOURCE[../libcrypto]=$UTIL_COMMON \
punycode.c passphrase.c sleep.c deterministic_nonce.c quic_vlint.c \
time.c
SOURCE[../providers/libfips.a]=$UTIL_COMMON
SOURCE[../providers/libfips.a]=time.c
SOURCE[../libcrypto]=$UPLINKSRC
DEFINE[../libcrypto]=$UPLINKDEF

View File

@ -62,10 +62,19 @@ void ossl_crypto_condvar_wait(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex)
{
}
void ossl_crypto_condvar_wait_timeout(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex,
OSSL_TIME deadline)
{
}
void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR *cv)
{
}
void ossl_crypto_condvar_signal(CRYPTO_CONDVAR *cv)
{
}
void ossl_crypto_condvar_free(CRYPTO_CONDVAR **cv)
{
}

View File

@ -204,6 +204,14 @@ void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR *cv)
pthread_cond_broadcast(cv_p);
}
void ossl_crypto_condvar_signal(CRYPTO_CONDVAR *cv)
{
pthread_cond_t *cv_p;
cv_p = (pthread_cond_t *)cv;
pthread_cond_signal(cv_p);
}
void ossl_crypto_condvar_free(CRYPTO_CONDVAR **cv)
{
pthread_cond_t **cv_p;

View File

@ -26,7 +26,7 @@ static DWORD __stdcall thread_start_thunk(LPVOID vthread)
ossl_crypto_mutex_lock(thread->statelock);
CRYPTO_THREAD_SET_STATE(thread, CRYPTO_THREAD_FINISHED);
thread->retval = ret;
ossl_crypto_condvar_broadcast(thread->condvar);
ossl_crypto_condvar_signal(thread->condvar);
ossl_crypto_mutex_unlock(thread->statelock);
return 0;
@ -142,6 +142,97 @@ void ossl_crypto_mutex_free(CRYPTO_MUTEX **mutex)
*mutex = NULL;
}
static int determine_timeout(OSSL_TIME deadline, DWORD *w_timeout_p)
{
OSSL_TIME now, delta;
uint64_t ms;
if (ossl_time_is_infinite(deadline)) {
*w_timeout_p = INFINITE;
return 1;
}
now = ossl_time_now();
delta = ossl_time_subtract(deadline, now);
if (ossl_time_is_zero(delta))
return 0;
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))
*w_timeout_p = INFINITE - 1;
else
*w_timeout_p = (DWORD)ms;
return 1;
}
# if defined(OPENSSL_THREADS_WINNT_LEGACY)
CRYPTO_CONDVAR *ossl_crypto_condvar_new(void)
{
HANDLE h;
if ((h = CreateEventA(NULL, FALSE, FALSE, NULL)) == NULL)
return NULL;
return (CRYPTO_CONDVAR *)h;
}
void ossl_crypto_condvar_wait(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex)
{
ossl_crypto_mutex_unlock(mutex);
WaitForSingleObject((HANDLE)cv, INFINITE);
ossl_crypto_mutex_lock(mutex);
}
void ossl_crypto_condvar_wait_timeout(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex,
OSSL_TIME deadline)
{
DWORD timeout;
fprintf(stderr, "# wt\n"); fflush(stderr);
if (!determine_timeout(deadline, &timeout))
timeout = 1;
ossl_crypto_mutex_unlock(mutex);
WaitForSingleObject((HANDLE)cv, timeout);
fprintf(stderr, "# wtd\n"); fflush(stderr);
ossl_crypto_mutex_lock(mutex);
fprintf(stderr, "# wtd2\n"); fflush(stderr);
}
void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR *cv)
{
/* Not supported */
}
void ossl_crypto_condvar_signal(CRYPTO_CONDVAR *cv)
{
HANDLE *cv_p = (HANDLE *)cv;
SetEvent(cv_p);
}
void ossl_crypto_condvar_free(CRYPTO_CONDVAR **cv)
{
HANDLE **cv_p;
cv_p = (HANDLE **)cv;
if (*cv_p != NULL)
CloseHandle(*cv_p);
*cv_p = NULL;
}
# else
CRYPTO_CONDVAR *ossl_crypto_condvar_new(void)
{
CONDITION_VARIABLE *cv_p;
@ -163,41 +254,16 @@ void ossl_crypto_condvar_wait(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex)
}
void ossl_crypto_condvar_wait_timeout(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex,
OSSL_TIME deadline, int *timeout_expired)
OSSL_TIME deadline)
{
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 (!determine_timeout(deadline, &timeout))
timeout = 1;
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;
SleepConditionVariableCS(cv_p, mutex_p, timeout);
}
void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR *cv)
@ -208,6 +274,14 @@ void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR *cv)
WakeAllConditionVariable(cv_p);
}
void ossl_crypto_condvar_signal(CRYPTO_CONDVAR *cv)
{
CONDITION_VARIABLE *cv_p;
cv_p = (CONDITION_VARIABLE *)cv;
WakeConditionVariable(cv_p);
}
void ossl_crypto_condvar_free(CRYPTO_CONDVAR **cv)
{
CONDITION_VARIABLE **cv_p;
@ -218,3 +292,10 @@ void ossl_crypto_condvar_free(CRYPTO_CONDVAR **cv)
}
#endif
void ossl_crypto_mem_barrier(void)
{
MemoryBarrier();
}
#endif

View File

@ -25,6 +25,9 @@
defined(_WIN32_WINNT)
# if _WIN32_WINNT >= 0x0600
# define OPENSSL_THREADS_WINNT
# elif _WIN32_WINNT >= 0x0501
# define OPENSSL_THREADS_WINNT
# define OPENSSL_THREADS_WINNT_LEGACY
# else
# define OPENSSL_THREADS_NONE
# endif
@ -48,6 +51,7 @@ void ossl_crypto_condvar_wait(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex);
void ossl_crypto_condvar_wait_timeout(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex,
OSSL_TIME deadline);
void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR *cv);
void ossl_crypto_condvar_signal(CRYPTO_CONDVAR *cv);
void ossl_crypto_condvar_free(CRYPTO_CONDVAR **cv);
typedef uint32_t CRYPTO_THREAD_RETVAL;

View File

@ -85,7 +85,7 @@ int ossl_quic_thread_assist_stop_async(QUIC_THREAD_ASSIST *qta)
{
if (!qta->teardown) {
qta->teardown = 1;
ossl_crypto_condvar_broadcast(qta->cv);
ossl_crypto_condvar_signal(qta->cv);
}
return 1;
@ -133,11 +133,7 @@ int ossl_quic_thread_assist_notify_deadline_changed(QUIC_THREAD_ASSIST *qta)
if (qta->teardown)
return 0;
/*
* Wake-one would be better here but as there is only one listening thread
* this does not actually matter.
*/
ossl_crypto_condvar_broadcast(qta->cv);
ossl_crypto_condvar_signal(qta->cv);
return 1;
}

View File

@ -324,9 +324,10 @@ static int do_test(int use_thread_assist, int use_fake_time, int use_inject)
* This is inefficient because we spin until things work without
* blocking but this is just a test.
*/
if (!c_start_idle_test || c_done_idle_test)
if (!c_start_idle_test || c_done_idle_test) {
/* Inhibit manual ticking during idle test to test TA mode. */
SSL_tick(c_ssl);
}
ossl_quic_tserver_tick(tserver);