QUIC Thread Assisted Mode: Support Windows XP
authorHugo Landau <hlandau@openssl.org>
Wed, 22 Feb 2023 19:15:16 +0000 (19:15 +0000)
committerHugo Landau <hlandau@openssl.org>
Thu, 30 Mar 2023 10:14:09 +0000 (11:14 +0100)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20348)

crypto/build.info
crypto/thread/arch/thread_none.c
crypto/thread/arch/thread_posix.c
crypto/thread/arch/thread_win.c
include/internal/thread_arch.h
ssl/quic/quic_thread_assist.c
test/quic_tserver_test.c

index 5c45cd703bf6e52dc8fff6368f70c66f95594d31..36856561ba71b3f235c6af2759380508ff1e6811 100644 (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
index c9c047c8e7817472d3ea3eb85838c8a2b63c33a2..675944bc5296f139cbaded9d39bf7cfb222269ed 100644 (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)
 {
 }
index ae79fe579c6927e6a9dd53847f04daa81c0cc1d6..0ab27b12302dd0a89a51c73c989270f2d0e0bfb2 100644 (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;
index 38a3e9a75bf513dc015eabcafa0520dfe2586e3c..cfda50f0beda4058990ead5c06a9c197f05b4679 100644 (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 (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 (!determine_timeout(deadline, &timeout))
+        timeout = 1;
 
-    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
index c8607d50a4a0b28c8f34a4ff675da0bad7d3b83c..24280d9706527f957cbea65db821d073ce2377da 100644 (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;
index 3e2ff1bc6fb8f9d86d722c2c5d7532f9816e7ff4..93d246ea8e1ebd08451660b45ed10cd25ab43ccc 100644 (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;
 }
 
index e5391648a3a80077b772b741eb08fb279ae8f6cf..359b66c1b251b44077af0523314bd253fc114f27 100644 (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);