Home | History | Annotate | Line # | Download | only in internal
      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 #ifndef OSSL_QUIC_THREAD_ASSIST_H
     11 #define OSSL_QUIC_THREAD_ASSIST_H
     12 
     13 #include <openssl/ssl.h>
     14 #include "internal/thread.h"
     15 #include "internal/time.h"
     16 
     17 #if defined(OPENSSL_NO_QUIC) || defined(OPENSSL_NO_THREAD_POOL)
     18 #define OPENSSL_NO_QUIC_THREAD_ASSIST
     19 #endif
     20 
     21 #ifndef OPENSSL_NO_QUIC_THREAD_ASSIST
     22 
     23 /*
     24  * QUIC Thread Assisted Functionality
     25  * ==================================
     26  *
     27  * Where OS threading support is available, QUIC can optionally support a thread
     28  * assisted mode of operation. The purpose of this mode of operation is to
     29  * ensure that assorted timeout events which QUIC expects to be handled in a
     30  * timely manner can be handled without the application needing to ensure that
     31  * SSL_tick() is called  on  time. This is not needed if the application always
     32  * has a call blocking to SSL_read() or SSL_write() (or another I/O function) on
     33  * a QUIC SSL object, but if the application goes for long periods of time
     34  * without making any such call to a QUIC SSL object, libssl cannot ordinarily
     35  * guarantee that QUIC timeout events will be serviced in a timely fashion.
     36  * Thread assisted  mode is therefore of use to applications which do not always
     37  * have an ongoing call to an I/O function on a QUIC SSL object but also do not
     38  * want to have to arrange periodic ticking.
     39  *
     40  * A consequence of this is that the intrusiveness of thread assisted mode upon
     41  * the general architecture of our QUIC engine is actually fairly limited and
     42  * amounts to an automatic ticking of the QUIC engine when timeouts expire,
     43  * synchronised correctly with an application's own threads using locking.
     44  */
     45 typedef struct quic_thread_assist_st {
     46     QUIC_CHANNEL *ch;
     47     CRYPTO_CONDVAR *cv;
     48     CRYPTO_THREAD *t;
     49     int teardown, joined;
     50 } QUIC_THREAD_ASSIST;
     51 
     52 /*
     53  * Initialise the thread assist object. The channel must have a valid mutex
     54  * configured on it which will be retrieved automatically. It is assumed that
     55  * the mutex is currently held when this function is called. This function does
     56  * not affect the state of the mutex.
     57  */
     58 int ossl_quic_thread_assist_init_start(QUIC_THREAD_ASSIST *qta,
     59     QUIC_CHANNEL *ch);
     60 
     61 /*
     62  * Request the thread assist helper to begin stopping the assist thread. This
     63  * returns before the teardown is complete. Idempotent; multiple calls to this
     64  * function are inconsequential.
     65  *
     66  * Precondition: channel mutex must be held (unchecked)
     67  */
     68 int ossl_quic_thread_assist_stop_async(QUIC_THREAD_ASSIST *qta);
     69 
     70 /*
     71  * Wait until the thread assist helper is torn down. This automatically implies
     72  * the effects of ossl_quic_thread_assist_stop_async(). Returns immediately
     73  * if the teardown has already completed.
     74  *
     75  * Precondition: channel mutex must be held (unchecked)
     76  */
     77 int ossl_quic_thread_assist_wait_stopped(QUIC_THREAD_ASSIST *qta);
     78 
     79 /*
     80  * Deallocates state associated with the thread assist helper.
     81  * ossl_quic_thread_assist_wait_stopped() must have returned successfully before
     82  * calling this. It does not matter whether the channel mutex is held or not.
     83  *
     84  * Precondition: ossl_quic_thread_assist_wait_stopped() has returned 1
     85  *               (asserted)
     86  */
     87 int ossl_quic_thread_assist_cleanup(QUIC_THREAD_ASSIST *qta);
     88 
     89 /*
     90  * Must be called to notify the assist thread if the channel deadline changes.
     91  *
     92  * Precondition: channel mutex must be held (unchecked)
     93  */
     94 int ossl_quic_thread_assist_notify_deadline_changed(QUIC_THREAD_ASSIST *qta);
     95 
     96 #endif
     97 
     98 #endif
     99