QUIC Thread Assisted Mode: Support Windows XP
[openssl.git] / crypto / thread / arch / thread_posix.c
index d74cfddab3792ef05993635abdb8fe43595d3278..0ab27b12302dd0a89a51c73c989270f2d0e0bfb2 100644 (file)
@@ -22,9 +22,6 @@ static void *thread_start_thunk(void *vthread)
 
     thread = (CRYPTO_THREAD *)vthread;
 
-    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
-    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
-
     ret = thread->routine(thread->data);
     ossl_crypto_mutex_lock(thread->statelock);
     CRYPTO_THREAD_SET_STATE(thread, CRYPTO_THREAD_FINISHED);
@@ -63,95 +60,25 @@ fail:
     return 0;
 }
 
-int ossl_crypto_thread_native_join(CRYPTO_THREAD *thread, CRYPTO_THREAD_RETVAL *retval)
+int ossl_crypto_thread_native_perform_join(CRYPTO_THREAD *thread, CRYPTO_THREAD_RETVAL *retval)
 {
     void *thread_retval;
     pthread_t *handle;
-    uint64_t req_state_mask;
 
-    if (thread == NULL)
+    if (thread == NULL || thread->handle == NULL)
         return 0;
 
-    req_state_mask = CRYPTO_THREAD_TERMINATED | CRYPTO_THREAD_JOINED;
-
-    ossl_crypto_mutex_lock(thread->statelock);
-    if (CRYPTO_THREAD_GET_STATE(thread, req_state_mask)) {
-        ossl_crypto_mutex_unlock(thread->statelock);
-        goto pass;
-    }
-    while (!CRYPTO_THREAD_GET_STATE(thread, CRYPTO_THREAD_FINISHED))
-        ossl_crypto_condvar_wait(thread->condvar, thread->statelock);
-    ossl_crypto_mutex_unlock(thread->statelock);
-
     handle = (pthread_t *) thread->handle;
-    if (handle == NULL)
-        goto fail;
-
     if (pthread_join(*handle, &thread_retval) != 0)
-        goto fail;
+        return 0;
 
     /*
      * Join return value may be non-NULL when the thread has been cancelled,
      * as indicated by thread_retval set to PTHREAD_CANCELLED.
      */
     if (thread_retval != NULL)
-        goto fail;
-
-pass:
-    if (retval != NULL)
-        *retval = thread->retval;
-
-    ossl_crypto_mutex_lock(thread->statelock);
-    CRYPTO_THREAD_UNSET_ERROR(thread, CRYPTO_THREAD_JOINED);
-    CRYPTO_THREAD_SET_STATE(thread, CRYPTO_THREAD_JOINED);
-    ossl_crypto_mutex_unlock(thread->statelock);
-    return 1;
-
-fail:
-    ossl_crypto_mutex_lock(thread->statelock);
-    CRYPTO_THREAD_SET_ERROR(thread, CRYPTO_THREAD_JOINED);
-    ossl_crypto_mutex_unlock(thread->statelock);
-    return 0;
-}
-
-int ossl_crypto_thread_native_terminate(CRYPTO_THREAD *thread)
-{
-    void *res;
-    uint64_t mask;
-    pthread_t *handle;
-
-    mask = CRYPTO_THREAD_FINISHED;
-    mask |= CRYPTO_THREAD_TERMINATED;
-    mask |= CRYPTO_THREAD_JOINED;
-
-    if (thread == NULL)
         return 0;
 
-    ossl_crypto_mutex_lock(thread->statelock);
-    if (thread->handle == NULL || CRYPTO_THREAD_GET_STATE(thread, mask))
-        goto terminated;
-    ossl_crypto_mutex_unlock(thread->statelock);
-
-    handle = thread->handle;
-    if (pthread_cancel(*handle) != 0) {
-        ossl_crypto_mutex_lock(thread->statelock);
-        CRYPTO_THREAD_SET_ERROR(thread, CRYPTO_THREAD_TERMINATED);
-        ossl_crypto_mutex_unlock(thread->statelock);
-        return 0;
-    }
-    if (pthread_join(*handle, &res) != 0)
-        return 0;
-    if (res != PTHREAD_CANCELED)
-        return 0;
-
-    thread->handle = NULL;
-    OPENSSL_free(handle);
-
-    ossl_crypto_mutex_lock(thread->statelock);
-terminated:
-    CRYPTO_THREAD_UNSET_ERROR(thread, CRYPTO_THREAD_TERMINATED);
-    CRYPTO_THREAD_SET_STATE(thread, CRYPTO_THREAD_TERMINATED);
-    ossl_crypto_mutex_unlock(thread->statelock);
     return 1;
 }
 
@@ -244,6 +171,31 @@ void ossl_crypto_condvar_wait(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex)
     pthread_cond_wait(cv_p, mutex_p);
 }
 
+void ossl_crypto_condvar_wait_timeout(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex,
+                                      OSSL_TIME deadline)
+{
+    pthread_cond_t *cv_p = (pthread_cond_t *)cv;
+    pthread_mutex_t *mutex_p = (pthread_mutex_t *)mutex;
+
+    if (ossl_time_is_infinite(deadline)) {
+        /*
+         * No deadline. Some pthread implementations allow
+         * pthread_cond_timedwait to work the same as pthread_cond_wait when
+         * abstime is NULL, but it is unclear whether this is POSIXly correct.
+         */
+        pthread_cond_wait(cv_p, mutex_p);
+    } else {
+        struct timespec deadline_ts;
+
+        deadline_ts.tv_sec
+            = ossl_time2seconds(deadline);
+        deadline_ts.tv_nsec
+            = (ossl_time2ticks(deadline) % OSSL_TIME_SECOND) / OSSL_TIME_NS;
+
+        pthread_cond_timedwait(cv_p, mutex_p, &deadline_ts);
+    }
+}
+
 void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR *cv)
 {
     pthread_cond_t *cv_p;
@@ -252,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;
@@ -266,40 +226,4 @@ void ossl_crypto_condvar_free(CRYPTO_CONDVAR **cv)
     *cv_p = NULL;
 }
 
-void ossl_crypto_mem_barrier(void)
-{
-# if defined(__clang__) || defined(__GNUC__)
-    __sync_synchronize();
-# elif !defined(OPENSSL_NO_ASM)
-#  if defined(__alpha__) /* Alpha */
-    __asm__ volatile("mb" : : : "memory");
-#  elif defined(__amd64__) || defined(__i386__) || defined(__i486__) \
-    || defined(__i586__)  || defined(__i686__) || defined(__i386) /* x86 */
-    __asm__ volatile("mfence" : : : "memory");
-#  elif defined(__arm__) || defined(__aarch64__) /* ARMv7, ARMv8 */
-    __asm__ volatile("dmb ish" : : : "memory");
-#  elif defined(__hppa__) /* PARISC */
-    __asm__ volatile("" : : : "memory");
-#  elif defined(__mips__) /* MIPS */
-    __asm__ volatile("sync" : : : "memory");
-#  elif defined(__powerpc__) || defined(__powerpc64__) /* power, ppc64, ppc64le */
-    __asm__ volatile("sync" : : : "memory");
-#  elif defined(__sparc__)
-    __asm__ volatile("ba,pt    %%xcc, 1f\n\t" \
-                     " membar  #Sync\n"   \
-                     "1:\n"                \
-                     : : : "memory");
-#  elif defined(__s390__) || defined(__s390x__) /* z */
-    __asm__ volatile("bcr 15,0" : : : "memory");
-#  elif defined(__riscv) || defined(__riscv__) /* riscv */
-    __asm__ volatile("fence iorw,iorw" : : : "memory");
-#  else /* others, compiler only */
-    __asm__ volatile("" : : : "memory");
-#  endif
-# else
-    /* compiler only barrier */
-    __asm__ volatile("" : : : "memory");
-# endif
-}
-
 #endif