quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

ares_event_select.c (4451B)


      1 /* MIT License
      2  *
      3  * Copyright (c) 2024 Brad House
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a copy
      6  * of this software and associated documentation files (the "Software"), to deal
      7  * in the Software without restriction, including without limitation the rights
      8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      9  * copies of the Software, and to permit persons to whom the Software is
     10  * furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  *
     24  * SPDX-License-Identifier: MIT
     25  */
     26 
     27 /* Some systems might default to something low like 256 (NetBSD), lets define
     28  * this to assist.  Really, no one should be using select, but lets be safe
     29  * anyhow */
     30 #define FD_SETSIZE 4096
     31 
     32 #include "ares_private.h"
     33 #include "ares_event.h"
     34 
     35 /* All systems have select(), but not all have a way to wake, so we require
     36  * pipe() to wake the select() */
     37 #if defined(HAVE_PIPE) && defined(CARES_THREADS)
     38 
     39 #ifdef HAVE_SYS_SELECT_H
     40 #  include <sys/select.h>
     41 #endif
     42 
     43 static ares_bool_t ares_evsys_select_init(ares_event_thread_t *e)
     44 {
     45   e->ev_signal = ares_pipeevent_create(e);
     46   if (e->ev_signal == NULL) {
     47     return ARES_FALSE; /* LCOV_EXCL_LINE: UntestablePath */
     48   }
     49   return ARES_TRUE;
     50 }
     51 
     52 static void ares_evsys_select_destroy(ares_event_thread_t *e)
     53 {
     54   (void)e;
     55 }
     56 
     57 static ares_bool_t ares_evsys_select_event_add(ares_event_t *event)
     58 {
     59   (void)event;
     60   return ARES_TRUE;
     61 }
     62 
     63 static void ares_evsys_select_event_del(ares_event_t *event)
     64 {
     65   (void)event;
     66 }
     67 
     68 static void ares_evsys_select_event_mod(ares_event_t      *event,
     69                                         ares_event_flags_t new_flags)
     70 {
     71   (void)event;
     72   (void)new_flags;
     73 }
     74 
     75 static size_t ares_evsys_select_wait(ares_event_thread_t *e,
     76                                      unsigned long        timeout_ms)
     77 {
     78   size_t          num_fds = 0;
     79   ares_socket_t  *fdlist  = ares_htable_asvp_keys(e->ev_sock_handles, &num_fds);
     80   int             rv;
     81   size_t          cnt = 0;
     82   size_t          i;
     83   fd_set          read_fds;
     84   fd_set          write_fds;
     85   fd_set          except_fds;
     86   int             nfds = 0;
     87   struct timeval  tv;
     88   struct timeval *tout = NULL;
     89 
     90   FD_ZERO(&read_fds);
     91   FD_ZERO(&write_fds);
     92   FD_ZERO(&except_fds);
     93 
     94   for (i = 0; i < num_fds; i++) {
     95     const ares_event_t *ev =
     96       ares_htable_asvp_get_direct(e->ev_sock_handles, fdlist[i]);
     97     if (ev->flags & ARES_EVENT_FLAG_READ) {
     98       FD_SET(ev->fd, &read_fds);
     99     }
    100     if (ev->flags & ARES_EVENT_FLAG_WRITE) {
    101       FD_SET(ev->fd, &write_fds);
    102     }
    103     FD_SET(ev->fd, &except_fds);
    104     if (ev->fd + 1 > nfds) {
    105       nfds = ev->fd + 1;
    106     }
    107   }
    108 
    109   if (timeout_ms) {
    110     tv.tv_sec  = (int)(timeout_ms / 1000);
    111     tv.tv_usec = (int)((timeout_ms % 1000) * 1000);
    112     tout       = &tv;
    113   }
    114 
    115   rv = select(nfds, &read_fds, &write_fds, &except_fds, tout);
    116   if (rv > 0) {
    117     for (i = 0; i < num_fds; i++) {
    118       ares_event_t      *ev;
    119       ares_event_flags_t flags = 0;
    120 
    121       ev = ares_htable_asvp_get_direct(e->ev_sock_handles, fdlist[i]);
    122       if (ev == NULL || ev->cb == NULL) {
    123         continue; /* LCOV_EXCL_LINE: DefensiveCoding */
    124       }
    125 
    126       if (FD_ISSET(fdlist[i], &read_fds) || FD_ISSET(fdlist[i], &except_fds)) {
    127         flags |= ARES_EVENT_FLAG_READ;
    128       }
    129 
    130       if (FD_ISSET(fdlist[i], &write_fds)) {
    131         flags |= ARES_EVENT_FLAG_WRITE;
    132       }
    133 
    134       if (flags == 0) {
    135         continue;
    136       }
    137 
    138       cnt++;
    139 
    140       ev->cb(e, fdlist[i], ev->data, flags);
    141     }
    142   }
    143 
    144   ares_free(fdlist);
    145 
    146   return cnt;
    147 }
    148 
    149 const ares_event_sys_t ares_evsys_select = {
    150   "select",
    151   ares_evsys_select_init,
    152   ares_evsys_select_destroy,   /* NoOp */
    153   ares_evsys_select_event_add, /* NoOp */
    154   ares_evsys_select_event_del, /* NoOp */
    155   ares_evsys_select_event_mod, /* NoOp */
    156   ares_evsys_select_wait
    157 };
    158 
    159 #endif