# include "internal/quic_reactor.h"
# include "internal/quic_statm.h"
# include "internal/time.h"
+# include "internal/thread.h"
# ifndef OPENSSL_NO_QUIC
* channel. The instantiator of the channel is responsible for providing a
* mutex as this makes it easier to handle instantiation and teardown of
* channels in situations potentially requiring locking.
+ *
+ * Note that this is a MUTEX not a RWLOCK as it needs to be an OS mutex for
+ * compatibility with an OS's condition variable wait API, whereas RWLOCK
+ * may, depending on the build configuration, be implemented using an OS's
+ * mutex primitive or using its RW mutex primitive.
*/
- CRYPTO_RWLOCK *mutex;
+ CRYPTO_MUTEX *mutex;
} QUIC_CHANNEL_ARGS;
typedef struct quic_channel_st QUIC_CHANNEL;
* time; it does not belong to the channel but rather is presumed to belong to
* the owner of the channel.
*/
-CRYPTO_RWLOCK *ossl_quic_channel_get_mutex(QUIC_CHANNEL *ch);
+CRYPTO_MUTEX *ossl_quic_channel_get_mutex(QUIC_CHANNEL *ch);
# endif
*/
static int quic_lock(QUIC_CONNECTION *qc)
{
- return CRYPTO_THREAD_write_lock(qc->mutex);
+ ossl_crypto_mutex_lock(qc->mutex);
+ return 1;
}
/* Precondition: Channel mutex is held (unchecked) */
QUIC_NEEDS_LOCK
static void quic_unlock(QUIC_CONNECTION *qc)
{
- CRYPTO_THREAD_unlock(qc->mutex);
+ ossl_crypto_mutex_unlock(qc->mutex);
}
if (qc->tls == NULL || (sc = SSL_CONNECTION_FROM_SSL(qc->tls)) == NULL)
goto err;
- if ((qc->mutex = CRYPTO_THREAD_lock_new()) == NULL)
+ if ((qc->mutex = ossl_crypto_mutex_new()) == NULL)
goto err;
qc->is_thread_assisted
/* Note: SSL_free calls OPENSSL_free(qc) for us */
SSL_free(qc->tls);
- CRYPTO_THREAD_lock_free(qc->mutex);
+ ossl_crypto_mutex_free(&qc->mutex);
}
/* SSL method init */
args.propq = qc->ssl.ctx->propq;
args.is_server = 0;
args.tls = qc->tls;
+ args.mutex = qc->mutex;
qc->ch = ossl_quic_channel_new(&args);
if (qc->ch == NULL)
QUIC_NEEDS_LOCK
static int ensure_channel_and_start(QUIC_CONNECTION *qc)
{
- if (!ensure_channel(qc))
- return 0;
-
- if (!configure_channel(qc)
- || !ossl_quic_channel_start(qc->ch))
- goto err;
+ if (!qc->started) {
+ if (!ensure_channel(qc))
+ return 0;
- qc->stream0 = ossl_quic_channel_get_stream_by_id(qc->ch, 0);
- if (qc->stream0 == NULL)
- goto err;
+ if (!configure_channel(qc)
+ || !ossl_quic_channel_start(qc->ch))
+ goto err;
- if (qc->is_thread_assisted)
- if (!ossl_quic_thread_assist_init_start(&qc->thread_assist, qc->ch))
+ qc->stream0 = ossl_quic_channel_get_stream_by_id(qc->ch, 0);
+ if (qc->stream0 == NULL)
goto err;
+ if (qc->is_thread_assisted)
+ if (!ossl_quic_thread_assist_init_start(&qc->thread_assist, qc->ch))
+ goto err;
+ }
+
qc->started = 1;
return 1;
CRYPTO_MUTEX *m = ossl_quic_channel_get_mutex(qta->ch);
QUIC_REACTOR *rtor;
- if (!CRYPTO_THREAD_write_lock(m))
- return 0;
+ ossl_crypto_mutex_lock(m);
rtor = ossl_quic_channel_get_reactor(qta->ch);
ossl_quic_reactor_tick(rtor, QUIC_REACTOR_TICK_FLAG_CHANNEL_ONLY);
}
- CRYPTO_THREAD_unlock(m);
+ ossl_crypto_mutex_unlock(m);
return 1;
}
return 1;
}
-static void ignore_res(int x) {}
-
int ossl_quic_thread_assist_wait_stopped(QUIC_THREAD_ASSIST *qta)
{
CRYPTO_THREAD_RETVAL rv;
- CRYPTO_RWLOCK *m = ossl_quic_channel_get_mutex(qta->ch);
+ CRYPTO_MUTEX *m = ossl_quic_channel_get_mutex(qta->ch);
if (qta->joined)
return 1;
if (!ossl_quic_thread_assist_stop_async(qta))
return 0;
- CRYPTO_THREAD_unlock(m);
+ ossl_crypto_mutex_unlock(m);
if (!ossl_crypto_thread_native_join(qta->t, &rv)) {
- ignore_res(CRYPTO_THREAD_write_lock(m)); /* best effort */
+ ossl_crypto_mutex_lock(m);
return 0;
}
qta->joined = 1;
- if (!CRYPTO_THREAD_write_lock(m))
- return 0;
-
+ ossl_crypto_mutex_lock(m);
return 1;
}