quickjs-tart

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

ares_timeout.c (4247B)


      1 /* MIT License
      2  *
      3  * Copyright (c) 1998 Massachusetts Institute of Technology
      4  * Copyright (c) The c-ares project and its contributors
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a copy
      7  * of this software and associated documentation files (the "Software"), to deal
      8  * in the Software without restriction, including without limitation the rights
      9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10  * copies of the Software, and to permit persons to whom the Software is
     11  * furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the next
     14  * paragraph) shall be included in all copies or substantial portions of the
     15  * Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     23  * SOFTWARE.
     24  *
     25  * SPDX-License-Identifier: MIT
     26  */
     27 
     28 #include "ares_private.h"
     29 
     30 #ifdef HAVE_LIMITS_H
     31 #  include <limits.h>
     32 #endif
     33 
     34 
     35 void ares_timeval_remaining(ares_timeval_t       *remaining,
     36                             const ares_timeval_t *now,
     37                             const ares_timeval_t *tout)
     38 {
     39   memset(remaining, 0, sizeof(*remaining));
     40 
     41   /* Expired! */
     42   if (tout->sec < now->sec ||
     43       (tout->sec == now->sec && tout->usec < now->usec)) {
     44     return;
     45   }
     46 
     47   remaining->sec = tout->sec - now->sec;
     48   if (tout->usec < now->usec) {
     49     remaining->sec  -= 1;
     50     remaining->usec  = (tout->usec + 1000000) - now->usec;
     51   } else {
     52     remaining->usec = tout->usec - now->usec;
     53   }
     54 }
     55 
     56 void ares_timeval_diff(ares_timeval_t *tvdiff, const ares_timeval_t *tvstart,
     57                        const ares_timeval_t *tvstop)
     58 {
     59   tvdiff->sec = tvstop->sec - tvstart->sec;
     60   if (tvstop->usec > tvstart->usec) {
     61     tvdiff->usec = tvstop->usec - tvstart->usec;
     62   } else {
     63     tvdiff->sec  -= 1;
     64     tvdiff->usec  = tvstop->usec + 1000000 - tvstart->usec;
     65   }
     66 }
     67 
     68 static void ares_timeval_to_struct_timeval(struct timeval       *tv,
     69                                            const ares_timeval_t *atv)
     70 {
     71 #ifdef USE_WINSOCK
     72   tv->tv_sec = (long)atv->sec;
     73 #else
     74   tv->tv_sec = (time_t)atv->sec;
     75 #endif
     76 
     77   tv->tv_usec = (int)atv->usec;
     78 }
     79 
     80 static void struct_timeval_to_ares_timeval(ares_timeval_t       *atv,
     81                                            const struct timeval *tv)
     82 {
     83   atv->sec  = (ares_int64_t)tv->tv_sec;
     84   atv->usec = (unsigned int)tv->tv_usec;
     85 }
     86 
     87 static struct timeval *ares_timeout_int(const ares_channel_t *channel,
     88                                         struct timeval       *maxtv,
     89                                         struct timeval       *tvbuf)
     90 {
     91   const ares_query_t *query;
     92   ares_slist_node_t  *node;
     93   ares_timeval_t      now;
     94   ares_timeval_t      atvbuf;
     95   ares_timeval_t      amaxtv;
     96 
     97   /* The minimum timeout of all queries is always the first entry in
     98    * channel->queries_by_timeout */
     99   node = ares_slist_node_first(channel->queries_by_timeout);
    100   /* no queries/timeout */
    101   if (node == NULL) {
    102     return maxtv;
    103   }
    104 
    105   query = ares_slist_node_val(node);
    106 
    107   ares_tvnow(&now);
    108 
    109   ares_timeval_remaining(&atvbuf, &now, &query->timeout);
    110 
    111   ares_timeval_to_struct_timeval(tvbuf, &atvbuf);
    112 
    113   if (maxtv == NULL) {
    114     return tvbuf;
    115   }
    116 
    117   /* Return the minimum time between maxtv and tvbuf */
    118   struct_timeval_to_ares_timeval(&amaxtv, maxtv);
    119 
    120   if (atvbuf.sec > amaxtv.sec) {
    121     return maxtv;
    122   }
    123 
    124   if (atvbuf.sec < amaxtv.sec) {
    125     return tvbuf;
    126   }
    127 
    128   if (atvbuf.usec > amaxtv.usec) {
    129     return maxtv;
    130   }
    131 
    132   return tvbuf;
    133 }
    134 
    135 struct timeval *ares_timeout(const ares_channel_t *channel,
    136                              struct timeval *maxtv, struct timeval *tvbuf)
    137 {
    138   struct timeval *rv;
    139 
    140   if (channel == NULL || tvbuf == NULL) {
    141     return NULL;
    142   }
    143 
    144   ares_channel_lock(channel);
    145 
    146   rv = ares_timeout_int(channel, maxtv, tvbuf);
    147 
    148   ares_channel_unlock(channel);
    149 
    150   return rv;
    151 }