Home | History | Annotate | Line # | Download | only in rio
      1      1.1  christos /*
      2      1.1  christos  * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved.
      3      1.1  christos  *
      4      1.1  christos  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5      1.1  christos  * this file except in compliance with the License.  You can obtain a copy
      6      1.1  christos  * in the file LICENSE in the source distribution or at
      7      1.1  christos  * https://www.openssl.org/source/license.html
      8      1.1  christos  */
      9      1.1  christos 
     10      1.1  christos #include "internal/common.h"
     11      1.1  christos #include "internal/quic_ssl.h"
     12      1.1  christos #include "internal/quic_reactor_wait_ctx.h"
     13      1.1  christos #include <openssl/ssl.h>
     14      1.1  christos #include <openssl/err.h>
     15      1.1  christos #include "../ssl_local.h"
     16      1.1  christos #include "poll_builder.h"
     17      1.1  christos 
     18      1.1  christos #if defined(_AIX)
     19      1.1  christos /*
     20      1.1  christos  * Some versions of AIX define macros for events and revents for use when
     21      1.1  christos  * accessing pollfd structures (see Github issue #24236). That interferes
     22      1.1  christos  * with our use of these names here. We simply undef them.
     23      1.1  christos  */
     24  1.1.1.2  christos #undef revents
     25  1.1.1.2  christos #undef events
     26      1.1  christos #endif
     27      1.1  christos 
     28      1.1  christos #define ITEM_N(items, stride, n) \
     29  1.1.1.2  christos     (*(SSL_POLL_ITEM *)((char *)(items) + (n) * (stride)))
     30      1.1  christos 
     31  1.1.1.2  christos #define FAIL_FROM(n)                              \
     32  1.1.1.2  christos     do {                                          \
     33  1.1.1.2  christos         size_t j;                                 \
     34  1.1.1.2  christos                                                   \
     35  1.1.1.2  christos         for (j = (n); j < num_items; ++j)         \
     36  1.1.1.2  christos             ITEM_N(items, stride, j).revents = 0; \
     37  1.1.1.2  christos                                                   \
     38  1.1.1.2  christos         ok = 0;                                   \
     39  1.1.1.2  christos         goto out;                                 \
     40      1.1  christos     } while (0)
     41      1.1  christos 
     42  1.1.1.2  christos #define FAIL_ITEM(idx)                                          \
     43  1.1.1.2  christos     do {                                                        \
     44  1.1.1.2  christos         size_t idx_ = (idx);                                    \
     45  1.1.1.2  christos                                                                 \
     46  1.1.1.2  christos         ITEM_N(items, stride, idx_).revents = SSL_POLL_EVENT_F; \
     47  1.1.1.2  christos         ++result_count;                                         \
     48  1.1.1.2  christos         FAIL_FROM(idx_ + 1);                                    \
     49      1.1  christos     } while (0)
     50      1.1  christos 
     51      1.1  christos #ifndef OPENSSL_NO_QUIC
     52      1.1  christos static int poll_translate_ssl_quic(SSL *ssl,
     53  1.1.1.2  christos     QUIC_REACTOR_WAIT_CTX *wctx,
     54  1.1.1.2  christos     RIO_POLL_BUILDER *rpb,
     55  1.1.1.2  christos     uint64_t events,
     56  1.1.1.2  christos     int *abort_blocking)
     57      1.1  christos {
     58      1.1  christos     BIO_POLL_DESCRIPTOR rd, wd;
     59      1.1  christos     int fd1 = -1, fd2 = -1, fd_nfy = -1;
     60      1.1  christos     int fd1_r = 0, fd1_w = 0, fd2_w = 0;
     61      1.1  christos 
     62      1.1  christos     if (SSL_net_read_desired(ssl)) {
     63      1.1  christos         if (!SSL_get_rpoll_descriptor(ssl, &rd)) {
     64      1.1  christos             ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
     65  1.1.1.2  christos                 "SSL_poll requires the network BIOs underlying "
     66  1.1.1.2  christos                 "a QUIC SSL object provide poll descriptors");
     67      1.1  christos             return 0;
     68      1.1  christos         }
     69      1.1  christos 
     70      1.1  christos         if (rd.type != BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD) {
     71      1.1  christos             ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
     72  1.1.1.2  christos                 "SSL_poll requires the poll descriptors of the "
     73  1.1.1.2  christos                 "network BIOs underlying a QUIC SSL object be "
     74  1.1.1.2  christos                 "of socket type");
     75      1.1  christos             return 0;
     76      1.1  christos         }
     77      1.1  christos 
     78  1.1.1.2  christos         fd1 = rd.value.fd;
     79      1.1  christos         fd1_r = 1;
     80      1.1  christos     }
     81      1.1  christos 
     82      1.1  christos     if (SSL_net_write_desired(ssl)) {
     83      1.1  christos         if (!SSL_get_wpoll_descriptor(ssl, &wd)) {
     84      1.1  christos             ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
     85  1.1.1.2  christos                 "SSL_poll requires the network BIOs underlying "
     86  1.1.1.2  christos                 "a QUIC SSL object provide poll descriptors");
     87      1.1  christos             return 0;
     88      1.1  christos         }
     89      1.1  christos 
     90      1.1  christos         if (wd.type != BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD) {
     91      1.1  christos             ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
     92  1.1.1.2  christos                 "SSL_poll requires the poll descriptors of the "
     93  1.1.1.2  christos                 "network BIOs underlying a QUIC SSL object be "
     94  1.1.1.2  christos                 "of socket type");
     95      1.1  christos             return 0;
     96      1.1  christos         }
     97      1.1  christos 
     98  1.1.1.2  christos         fd2 = wd.value.fd;
     99      1.1  christos         fd2_w = 1;
    100      1.1  christos     }
    101      1.1  christos 
    102      1.1  christos     if (fd2 == fd1) {
    103      1.1  christos         fd2 = -1;
    104      1.1  christos         fd1_w = fd2_w;
    105      1.1  christos     }
    106      1.1  christos 
    107      1.1  christos     if (fd1 != -1)
    108      1.1  christos         if (!ossl_rio_poll_builder_add_fd(rpb, fd1, fd1_r, fd1_w))
    109      1.1  christos             return 0;
    110      1.1  christos 
    111      1.1  christos     if (fd2 != -1 && fd2_w)
    112  1.1.1.2  christos         if (!ossl_rio_poll_builder_add_fd(rpb, fd2, /*r = */ 0, fd2_w))
    113      1.1  christos             return 0;
    114      1.1  christos 
    115      1.1  christos     /*
    116      1.1  christos      * Add the notifier FD for the QUIC domain this SSL object is a part of (if
    117      1.1  christos      * there is one). This ensures we get woken up if another thread calls into
    118      1.1  christos      * that QUIC domain and some readiness event relevant to the SSL_poll call
    119      1.1  christos      * on this thread arises without the underlying network socket ever becoming
    120      1.1  christos      * readable.
    121      1.1  christos      */
    122      1.1  christos     fd_nfy = ossl_quic_get_notifier_fd(ssl);
    123      1.1  christos     if (fd_nfy != -1) {
    124      1.1  christos         uint64_t revents = 0;
    125      1.1  christos 
    126  1.1.1.2  christos         if (!ossl_rio_poll_builder_add_fd(rpb, fd_nfy, /*r = */ 1, /*w = */ 0))
    127      1.1  christos             return 0;
    128      1.1  christos 
    129      1.1  christos         /* Tell QUIC domain we need to receive notifications. */
    130      1.1  christos         ossl_quic_enter_blocking_section(ssl, wctx);
    131      1.1  christos 
    132      1.1  christos         /*
    133      1.1  christos          * Only after the above call returns is it guaranteed that any readiness
    134      1.1  christos          * events will cause the above notifier to become readable. Therefore,
    135      1.1  christos          * it is possible the object became ready after our initial
    136      1.1  christos          * poll_readout() call (before we determined that nothing was ready and
    137      1.1  christos          * we needed to block). We now need to do another readout, in which case
    138      1.1  christos          * blocking is to be aborted.
    139      1.1  christos          */
    140  1.1.1.2  christos         if (!ossl_quic_conn_poll_events(ssl, events, /*do_tick = */ 0, &revents)) {
    141      1.1  christos             ossl_quic_leave_blocking_section(ssl, wctx);
    142      1.1  christos             return 0;
    143      1.1  christos         }
    144      1.1  christos 
    145      1.1  christos         if (revents != 0) {
    146      1.1  christos             ossl_quic_leave_blocking_section(ssl, wctx);
    147      1.1  christos             *abort_blocking = 1;
    148      1.1  christos             return 1;
    149      1.1  christos         }
    150      1.1  christos     }
    151      1.1  christos 
    152      1.1  christos     return 1;
    153      1.1  christos }
    154      1.1  christos 
    155      1.1  christos static void postpoll_translation_cleanup_ssl_quic(SSL *ssl,
    156  1.1.1.2  christos     QUIC_REACTOR_WAIT_CTX *wctx)
    157      1.1  christos {
    158      1.1  christos     if (ossl_quic_get_notifier_fd(ssl) != -1)
    159      1.1  christos         ossl_quic_leave_blocking_section(ssl, wctx);
    160      1.1  christos }
    161      1.1  christos 
    162      1.1  christos static void postpoll_translation_cleanup(SSL_POLL_ITEM *items,
    163  1.1.1.2  christos     size_t num_items,
    164  1.1.1.2  christos     size_t stride,
    165  1.1.1.2  christos     QUIC_REACTOR_WAIT_CTX *wctx)
    166      1.1  christos {
    167      1.1  christos     SSL_POLL_ITEM *item;
    168      1.1  christos     SSL *ssl;
    169      1.1  christos     size_t i;
    170      1.1  christos 
    171      1.1  christos     for (i = 0; i < num_items; ++i) {
    172      1.1  christos         item = &ITEM_N(items, stride, i);
    173      1.1  christos 
    174      1.1  christos         switch (item->desc.type) {
    175      1.1  christos         case BIO_POLL_DESCRIPTOR_TYPE_SSL:
    176      1.1  christos             ssl = item->desc.value.ssl;
    177      1.1  christos             if (ssl == NULL)
    178      1.1  christos                 break;
    179      1.1  christos 
    180      1.1  christos             switch (ssl->type) {
    181  1.1.1.2  christos #ifndef OPENSSL_NO_QUIC
    182      1.1  christos             case SSL_TYPE_QUIC_LISTENER:
    183      1.1  christos             case SSL_TYPE_QUIC_CONNECTION:
    184      1.1  christos             case SSL_TYPE_QUIC_XSO:
    185      1.1  christos                 postpoll_translation_cleanup_ssl_quic(ssl, wctx);
    186      1.1  christos                 break;
    187  1.1.1.2  christos #endif
    188      1.1  christos             default:
    189      1.1  christos                 break;
    190      1.1  christos             }
    191      1.1  christos             break;
    192      1.1  christos         default:
    193      1.1  christos             break;
    194      1.1  christos         }
    195      1.1  christos     }
    196      1.1  christos }
    197      1.1  christos 
    198      1.1  christos static int poll_translate(SSL_POLL_ITEM *items,
    199  1.1.1.2  christos     size_t num_items,
    200  1.1.1.2  christos     size_t stride,
    201  1.1.1.2  christos     QUIC_REACTOR_WAIT_CTX *wctx,
    202  1.1.1.2  christos     RIO_POLL_BUILDER *rpb,
    203  1.1.1.2  christos     OSSL_TIME *p_earliest_wakeup_deadline,
    204  1.1.1.2  christos     int *abort_blocking,
    205  1.1.1.2  christos     size_t *p_result_count)
    206      1.1  christos {
    207      1.1  christos     int ok = 1;
    208      1.1  christos     SSL_POLL_ITEM *item;
    209      1.1  christos     size_t result_count = 0;
    210      1.1  christos     SSL *ssl;
    211      1.1  christos     OSSL_TIME earliest_wakeup_deadline = ossl_time_infinite();
    212      1.1  christos     struct timeval timeout;
    213      1.1  christos     int is_infinite = 0;
    214      1.1  christos     size_t i;
    215      1.1  christos 
    216      1.1  christos     for (i = 0; i < num_items; ++i) {
    217      1.1  christos         item = &ITEM_N(items, stride, i);
    218      1.1  christos 
    219      1.1  christos         switch (item->desc.type) {
    220      1.1  christos         case BIO_POLL_DESCRIPTOR_TYPE_SSL:
    221      1.1  christos             ssl = item->desc.value.ssl;
    222      1.1  christos             if (ssl == NULL)
    223      1.1  christos                 /* NULL items are no-ops and have revents reported as 0 */
    224      1.1  christos                 break;
    225      1.1  christos 
    226      1.1  christos             switch (ssl->type) {
    227  1.1.1.2  christos #ifndef OPENSSL_NO_QUIC
    228      1.1  christos             case SSL_TYPE_QUIC_LISTENER:
    229      1.1  christos             case SSL_TYPE_QUIC_CONNECTION:
    230      1.1  christos             case SSL_TYPE_QUIC_XSO:
    231      1.1  christos                 if (!poll_translate_ssl_quic(ssl, wctx, rpb, item->events,
    232  1.1.1.2  christos                         abort_blocking))
    233      1.1  christos                     FAIL_ITEM(i);
    234      1.1  christos 
    235      1.1  christos                 if (*abort_blocking)
    236      1.1  christos                     return 1;
    237      1.1  christos 
    238      1.1  christos                 if (!SSL_get_event_timeout(ssl, &timeout, &is_infinite))
    239      1.1  christos                     FAIL_ITEM(i++); /* need to clean up this item too */
    240      1.1  christos 
    241      1.1  christos                 if (!is_infinite)
    242      1.1  christos                     earliest_wakeup_deadline
    243      1.1  christos                         = ossl_time_min(earliest_wakeup_deadline,
    244  1.1.1.2  christos                             ossl_time_add(ossl_time_now(),
    245  1.1.1.2  christos                                 ossl_time_from_timeval(timeout)));
    246      1.1  christos 
    247      1.1  christos                 break;
    248  1.1.1.2  christos #endif
    249      1.1  christos 
    250      1.1  christos             default:
    251      1.1  christos                 ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
    252  1.1.1.2  christos                     "SSL_poll currently only supports QUIC SSL "
    253  1.1.1.2  christos                     "objects");
    254      1.1  christos                 FAIL_ITEM(i);
    255      1.1  christos             }
    256      1.1  christos             break;
    257      1.1  christos 
    258      1.1  christos         case BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD:
    259      1.1  christos             ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
    260  1.1.1.2  christos                 "SSL_poll currently does not support polling "
    261  1.1.1.2  christos                 "sockets");
    262      1.1  christos             FAIL_ITEM(i);
    263      1.1  christos 
    264      1.1  christos         default:
    265      1.1  christos             ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
    266  1.1.1.2  christos                 "SSL_poll does not support unknown poll descriptor "
    267  1.1.1.2  christos                 "type %d",
    268  1.1.1.2  christos                 item->desc.type);
    269      1.1  christos             FAIL_ITEM(i);
    270      1.1  christos         }
    271      1.1  christos     }
    272      1.1  christos 
    273      1.1  christos out:
    274      1.1  christos     if (!ok)
    275      1.1  christos         postpoll_translation_cleanup(items, i, stride, wctx);
    276      1.1  christos 
    277      1.1  christos     *p_earliest_wakeup_deadline = earliest_wakeup_deadline;
    278      1.1  christos     *p_result_count = result_count;
    279      1.1  christos     return ok;
    280      1.1  christos }
    281      1.1  christos 
    282      1.1  christos static int poll_block(SSL_POLL_ITEM *items,
    283  1.1.1.2  christos     size_t num_items,
    284  1.1.1.2  christos     size_t stride,
    285  1.1.1.2  christos     OSSL_TIME user_deadline,
    286  1.1.1.2  christos     size_t *p_result_count)
    287      1.1  christos {
    288      1.1  christos     int ok = 0, abort_blocking = 0;
    289      1.1  christos     RIO_POLL_BUILDER rpb;
    290      1.1  christos     QUIC_REACTOR_WAIT_CTX wctx;
    291      1.1  christos     OSSL_TIME earliest_wakeup_deadline;
    292      1.1  christos 
    293      1.1  christos     /*
    294      1.1  christos      * Blocking is somewhat involved and involves the following steps:
    295      1.1  christos      *
    296      1.1  christos      * - Translation, in which the various logical items (SSL objects, etc.) to
    297      1.1  christos      *   be polled are translated into items an OS polling API understands.
    298      1.1  christos      *
    299      1.1  christos      * - Synchronisation bookkeeping. This ensures that we can be woken up
    300      1.1  christos      *   not just by readiness of any underlying file descriptor distilled from
    301      1.1  christos      *   the provided items but also by other threads, which might do work
    302      1.1  christos      *   on a relevant QUIC object to cause the object to be ready without the
    303      1.1  christos      *   underlying file descriptor ever becoming ready from our perspective.
    304      1.1  christos      *
    305      1.1  christos      * - The blocking call to the OS polling API.
    306      1.1  christos      *
    307      1.1  christos      * - Currently we do not do reverse translation but simply call
    308      1.1  christos      *   poll_readout() again to read out all readiness state for all
    309      1.1  christos      *   descriptors which the user passed.
    310      1.1  christos      *
    311      1.1  christos      *   TODO(QUIC POLLING): In the future we will do reverse translation here
    312      1.1  christos      *   also to facilitate a more efficient readout.
    313      1.1  christos      */
    314      1.1  christos     ossl_quic_reactor_wait_ctx_init(&wctx);
    315      1.1  christos     ossl_rio_poll_builder_init(&rpb);
    316      1.1  christos 
    317      1.1  christos     if (!poll_translate(items, num_items, stride, &wctx, &rpb,
    318  1.1.1.2  christos             &earliest_wakeup_deadline,
    319  1.1.1.2  christos             &abort_blocking,
    320  1.1.1.2  christos             p_result_count))
    321      1.1  christos         goto out;
    322      1.1  christos 
    323      1.1  christos     if (abort_blocking)
    324      1.1  christos         goto out;
    325      1.1  christos 
    326      1.1  christos     earliest_wakeup_deadline = ossl_time_min(earliest_wakeup_deadline,
    327  1.1.1.2  christos         user_deadline);
    328      1.1  christos 
    329      1.1  christos     ok = ossl_rio_poll_builder_poll(&rpb, earliest_wakeup_deadline);
    330      1.1  christos 
    331      1.1  christos     postpoll_translation_cleanup(items, num_items, stride, &wctx);
    332      1.1  christos 
    333      1.1  christos out:
    334      1.1  christos     ossl_rio_poll_builder_cleanup(&rpb);
    335      1.1  christos     ossl_quic_reactor_wait_ctx_cleanup(&wctx);
    336      1.1  christos     return ok;
    337      1.1  christos }
    338      1.1  christos #endif
    339      1.1  christos 
    340      1.1  christos static int poll_readout(SSL_POLL_ITEM *items,
    341  1.1.1.2  christos     size_t num_items,
    342  1.1.1.2  christos     size_t stride,
    343  1.1.1.2  christos     int do_tick,
    344  1.1.1.2  christos     size_t *p_result_count)
    345      1.1  christos {
    346      1.1  christos     int ok = 1;
    347      1.1  christos     size_t i, result_count = 0;
    348      1.1  christos     SSL_POLL_ITEM *item;
    349      1.1  christos     SSL *ssl;
    350      1.1  christos #ifndef OPENSSL_NO_QUIC
    351      1.1  christos     uint64_t events;
    352      1.1  christos #endif
    353      1.1  christos     uint64_t revents;
    354      1.1  christos 
    355      1.1  christos     for (i = 0; i < num_items; ++i) {
    356  1.1.1.2  christos         item = &ITEM_N(items, stride, i);
    357      1.1  christos #ifndef OPENSSL_NO_QUIC
    358  1.1.1.2  christos         events = item->events;
    359      1.1  christos #endif
    360      1.1  christos         revents = 0;
    361      1.1  christos 
    362      1.1  christos         switch (item->desc.type) {
    363      1.1  christos         case BIO_POLL_DESCRIPTOR_TYPE_SSL:
    364      1.1  christos             ssl = item->desc.value.ssl;
    365      1.1  christos             if (ssl == NULL)
    366      1.1  christos                 /* NULL items are no-ops and have revents reported as 0 */
    367      1.1  christos                 break;
    368      1.1  christos 
    369      1.1  christos             switch (ssl->type) {
    370      1.1  christos #ifndef OPENSSL_NO_QUIC
    371      1.1  christos             case SSL_TYPE_QUIC_LISTENER:
    372      1.1  christos             case SSL_TYPE_QUIC_CONNECTION:
    373      1.1  christos             case SSL_TYPE_QUIC_XSO:
    374      1.1  christos                 if (!ossl_quic_conn_poll_events(ssl, events, do_tick, &revents))
    375      1.1  christos                     /* above call raises ERR */
    376      1.1  christos                     FAIL_ITEM(i);
    377      1.1  christos 
    378      1.1  christos                 if (revents != 0)
    379      1.1  christos                     ++result_count;
    380      1.1  christos 
    381      1.1  christos                 break;
    382      1.1  christos #endif
    383      1.1  christos 
    384      1.1  christos             default:
    385      1.1  christos                 ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
    386  1.1.1.2  christos                     "SSL_poll currently only supports QUIC SSL "
    387  1.1.1.2  christos                     "objects");
    388      1.1  christos                 FAIL_ITEM(i);
    389      1.1  christos             }
    390      1.1  christos             break;
    391      1.1  christos         case BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD:
    392      1.1  christos             ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
    393  1.1.1.2  christos                 "SSL_poll currently does not support polling "
    394  1.1.1.2  christos                 "sockets");
    395      1.1  christos             FAIL_ITEM(i);
    396      1.1  christos         default:
    397      1.1  christos             ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED,
    398  1.1.1.2  christos                 "SSL_poll does not support unknown poll descriptor "
    399  1.1.1.2  christos                 "type %d",
    400  1.1.1.2  christos                 item->desc.type);
    401      1.1  christos             FAIL_ITEM(i);
    402      1.1  christos         }
    403      1.1  christos 
    404      1.1  christos         item->revents = revents;
    405      1.1  christos     }
    406      1.1  christos 
    407      1.1  christos out:
    408      1.1  christos     if (p_result_count != NULL)
    409      1.1  christos         *p_result_count = result_count;
    410      1.1  christos 
    411      1.1  christos     return ok;
    412      1.1  christos }
    413      1.1  christos 
    414      1.1  christos int SSL_poll(SSL_POLL_ITEM *items,
    415  1.1.1.2  christos     size_t num_items,
    416  1.1.1.2  christos     size_t stride,
    417  1.1.1.2  christos     const struct timeval *timeout,
    418  1.1.1.2  christos     uint64_t flags,
    419  1.1.1.2  christos     size_t *p_result_count)
    420      1.1  christos {
    421      1.1  christos     int ok = 1;
    422      1.1  christos     size_t result_count = 0;
    423      1.1  christos     ossl_unused int do_tick = ((flags & SSL_POLL_FLAG_NO_HANDLE_EVENTS) == 0);
    424      1.1  christos     OSSL_TIME deadline;
    425      1.1  christos 
    426      1.1  christos     /* Trivial case. */
    427      1.1  christos     if (num_items == 0) {
    428      1.1  christos         if (timeout == NULL)
    429      1.1  christos             goto out;
    430      1.1  christos         OSSL_sleep(ossl_time2ms(ossl_time_from_timeval(*timeout)));
    431      1.1  christos         goto out;
    432      1.1  christos     }
    433      1.1  christos 
    434      1.1  christos     /* Convert timeout to deadline. */
    435      1.1  christos     if (timeout == NULL)
    436      1.1  christos         deadline = ossl_time_infinite();
    437      1.1  christos     else if (timeout->tv_sec == 0 && timeout->tv_usec == 0)
    438      1.1  christos         deadline = ossl_time_zero();
    439      1.1  christos     else
    440      1.1  christos         deadline = ossl_time_add(ossl_time_now(),
    441  1.1.1.2  christos             ossl_time_from_timeval(*timeout));
    442      1.1  christos 
    443      1.1  christos     /* Loop until we have something to report. */
    444      1.1  christos     for (;;) {
    445      1.1  christos         /* Readout phase - poll current state of each item. */
    446      1.1  christos         if (!poll_readout(items, num_items, stride, do_tick, &result_count)) {
    447      1.1  christos             ok = 0;
    448      1.1  christos             goto out;
    449      1.1  christos         }
    450      1.1  christos 
    451      1.1  christos         /*
    452      1.1  christos          * If we got anything, or we are in immediate mode (zero timeout), or
    453      1.1  christos          * the deadline has expired, we're done.
    454      1.1  christos          */
    455      1.1  christos         if (result_count > 0
    456      1.1  christos             || ossl_time_is_zero(deadline) /* (avoids now call) */
    457      1.1  christos             || ossl_time_compare(ossl_time_now(), deadline) >= 0)
    458      1.1  christos             goto out;
    459      1.1  christos 
    460      1.1  christos         /*
    461      1.1  christos          * Block until something is ready. Ignore NO_HANDLE_EVENTS from this
    462      1.1  christos          * point onwards.
    463      1.1  christos          */
    464      1.1  christos         do_tick = 1;
    465      1.1  christos #ifndef OPENSSL_NO_QUIC
    466      1.1  christos         if (!poll_block(items, num_items, stride, deadline, &result_count)) {
    467      1.1  christos             ok = 0;
    468      1.1  christos             goto out;
    469      1.1  christos         }
    470      1.1  christos #endif
    471      1.1  christos     }
    472      1.1  christos 
    473      1.1  christos     /* TODO(QUIC POLLING): Support for polling FDs */
    474      1.1  christos 
    475      1.1  christos out:
    476      1.1  christos     if (p_result_count != NULL)
    477      1.1  christos         *p_result_count = result_count;
    478      1.1  christos 
    479      1.1  christos     return ok;
    480      1.1  christos }
    481