1 2/* Copyright 1998 by the Massachusetts Institute of Technology. 3 * 4 * Permission to use, copy, modify, and distribute this 5 * software and its documentation for any purpose and without 6 * fee is hereby granted, provided that the above copyright 7 * notice appear in all copies and that both that copyright 8 * notice and this permission notice appear in supporting 9 * documentation, and that the name of M.I.T. not be used in 10 * advertising or publicity pertaining to distribution of the 11 * software without specific, written prior permission. 12 * M.I.T. makes no representations about the suitability of 13 * this software for any purpose. It is provided "as is" 14 * without express or implied warranty. 15 */ 16 17#include "ares_setup.h" 18 19#ifdef HAVE_SYS_TIME_H 20#include <sys/time.h> 21#endif 22 23#include <time.h> 24 25#include "ares.h" 26#include "ares_private.h" 27 28/* WARNING: Beware that this is linear in the number of outstanding 29 * requests! You are probably far better off just calling ares_process() 30 * once per second, rather than calling ares_timeout() to figure out 31 * when to next call ares_process(). 32 */ 33struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv, 34 struct timeval *tvbuf) 35{ 36 struct query *query; 37 struct list_node* list_head; 38 struct list_node* list_node; 39 struct timeval now; 40 struct timeval nextstop; 41 long offset, min_offset; 42 43 /* No queries, no timeout (and no fetch of the current time). */ 44 if (ares__is_list_empty(&(channel->all_queries))) 45 return maxtv; 46 47 /* Find the minimum timeout for the current set of queries. */ 48 now = ares__tvnow(); 49 min_offset = -1; 50 51 list_head = &(channel->all_queries); 52 for (list_node = list_head->next; list_node != list_head; 53 list_node = list_node->next) 54 { 55 query = list_node->data; 56 if (query->timeout.tv_sec == 0) 57 continue; 58 offset = ares__timeoffset(&now, &query->timeout); 59 if (offset < 0) 60 offset = 0; 61 if (min_offset == -1 || offset < min_offset) 62 min_offset = offset; 63 } 64 65 if(min_offset != -1) { 66 nextstop.tv_sec = min_offset/1000; 67 nextstop.tv_usec = (min_offset%1000)*1000; 68 } 69 70 /* If we found a minimum timeout and it's sooner than the one specified in 71 * maxtv (if any), return it. Otherwise go with maxtv. 72 */ 73 if (min_offset != -1 && (!maxtv || ares__timedout(maxtv, &nextstop))) 74 { 75 *tvbuf = nextstop; 76 return tvbuf; 77 } 78 else 79 return maxtv; 80} 81