Changeset 1402

Show
Ignore:
Timestamp:
09/22/09 12:14:43 (6 months ago)
Author:
ahu
Message:

implement timeouts with millisecond resolution, and raise the default timeout to 1500 msec.
In addition, the previous code may not actually have been delivering the "1 second" timeout accurately, this is now fixed

Location:
trunk/pdns/pdns
Files:
7 modified

Legend:

Unmodified
Added
Removed
  • trunk/pdns/pdns/dnsreplay.cc

    r1287 r1402  
    100100 
    101101 
    102 bool operator<(const struct timeval& lhs, const struct timeval& rhs)  
    103 { 
    104   return make_pair(lhs.tv_sec, lhs.tv_usec) < make_pair(rhs.tv_sec, rhs.tv_usec); 
    105 } 
    106102 
    107103 
  • trunk/pdns/pdns/lwres.cc

    r1349 r1402  
    106106     
    107107    ret=arecvfrom(reinterpret_cast<char *>(buf.get()), bufsize-1,0, ip, &len, pw.getHeader()->id,  
    108                   domain, type, queryfd, now->tv_sec); 
     108                  domain, type, queryfd, now); 
    109109  } 
    110110  else { 
  • trunk/pdns/pdns/lwres.hh

    r1349 r1402  
    4444            const string& domain, uint16_t qtype,  int* fd); 
    4545int arecvfrom(char *data, int len, int flags, const ComboAddress& ip, int *d_len, uint16_t id,  
    46               const string& domain, uint16_t, int fd, unsigned int now); 
     46              const string& domain, uint16_t, int fd, struct timeval* now); 
    4747 
    4848class LWResException : public AhuException 
  • trunk/pdns/pdns/misc.hh

    r1345 r1402  
    304304  return tv.tv_sec + tv.tv_usec/1000000.0f; 
    305305} 
     306 
     307inline bool operator<(const struct timeval& lhs, const struct timeval& rhs)  
     308{ 
     309  return make_pair(lhs.tv_sec, lhs.tv_usec) < make_pair(rhs.tv_sec, rhs.tv_usec); 
     310} 
     311 
    306312struct CIStringCompare: public binary_function<string, string, bool>   
    307313{ 
  • trunk/pdns/pdns/mtasker.cc

    r1260 r1402  
    159159*/ 
    160160 
    161 template<class EventKey, class EventVal>int MTasker<EventKey,EventVal>::waitEvent(EventKey &key, EventVal *val, unsigned int timeout, unsigned int now) 
     161template<class EventKey, class EventVal>int MTasker<EventKey,EventVal>::waitEvent(EventKey &key, EventVal *val, unsigned int timeoutMsec, struct timeval* now) 
    162162{ 
    163163  if(d_waiters.count(key)) { // there was already an exact same waiter 
     
    167167  Waiter w; 
    168168  w.context=new ucontext_t; 
    169   w.ttd=0; 
    170   if(timeout) 
    171     w.ttd= timeout + (now ? now : time(0)); 
     169  w.ttd.tv_sec = 0; w.ttd.tv_usec = 0; 
     170  if(timeoutMsec) { 
     171    struct timeval increment; 
     172    increment.tv_sec = timeoutMsec / 1000; 
     173    increment.tv_usec = 1000 * (timeoutMsec % 1000); 
     174    if(now)  
     175      w.ttd = increment + *now; 
     176    else { 
     177      struct timeval realnow; 
     178      gettimeofday(&realnow, 0); 
     179      w.ttd = increment + realnow; 
     180    } 
     181  } 
    172182 
    173183  w.tid=d_tid; 
    174    
    175184  w.key=key; 
    176185 
     
    268277       
    269278*/ 
    270 template<class Key, class Val>bool MTasker<Key,Val>::schedule(unsigned int now) 
     279template<class Key, class Val>bool MTasker<Key,Val>::schedule(struct timeval* now) 
    271280{ 
    272281  if(!d_runQueue.empty()) { 
     
    292301  } 
    293302  if(!d_waiters.empty()) { 
     303    struct timeval rnow; 
    294304    if(!now) 
    295       now=time(0); 
     305      gettimeofday(&rnow, 0); 
     306    else 
     307      rnow = *now; 
    296308 
    297309    typedef typename waiters_t::template index<KeyTag>::type waiters_by_ttd_index_t; 
     
    300312 
    301313    for(typename waiters_by_ttd_index_t::iterator i=ttdindex.begin(); i != ttdindex.end(); ) { 
    302       if(i->ttd && (unsigned int)i->ttd < now) { 
     314      if(i->ttd.tv_sec && i->ttd < rnow) { 
    303315        d_waitstatus=TimeOut; 
    304316        d_eventkey=i->key;        // pass waitEvent the exact key it was woken for 
     
    312324        delete uc; 
    313325      } 
    314       else if(i->ttd) 
     326      else if(i->ttd.tv_sec) 
    315327        break; 
    316328    } 
  • trunk/pdns/pdns/mtasker.hh

    r853 r1402  
    11/* 
    22    PowerDNS Versatile Database Driven Nameserver 
    3     Copyright (C) 2002 - 2006  PowerDNS.COM BV 
     3    Copyright (C) 2002 - 2009  PowerDNS.COM BV 
    44 
    55    This program is free software; you can redistribute it and/or modify 
     
    6666    EventKey key; 
    6767    ucontext_t *context; 
    68     time_t ttd; 
     68    struct timeval ttd; 
    6969    int tid; 
    7070  }; 
     
    7474    indexed_by < 
    7575                ordered_unique<member<Waiter,EventKey,&Waiter::key> >, 
    76                 ordered_non_unique<tag<KeyTag>, member<Waiter,time_t,&Waiter::ttd> > 
     76                ordered_non_unique<tag<KeyTag>, member<Waiter,struct timeval,&Waiter::ttd> > 
    7777               > 
    7878  > waiters_t; 
     
    9191 
    9292  typedef void tfunc_t(void *); //!< type of the pointer that starts a thread  
    93   int waitEvent(EventKey &key, EventVal *val=0, unsigned int timeout=0, unsigned int now=0); 
     93  int waitEvent(EventKey &key, EventVal *val=0, unsigned int timeoutMsec=0, struct timeval* now=0); 
    9494  void yield(); 
    9595  int sendEvent(const EventKey& key, const EventVal* val=0); 
    9696  void getEvents(std::vector<EventKey>& events); 
    9797  void makeThread(tfunc_t *start, void* val); 
    98   bool schedule(unsigned int now=0); 
     98  bool schedule(struct timeval* now=0); 
    9999  bool noProcesses(); 
    100100  unsigned int numProcesses(); 
  • trunk/pdns/pdns/pdns_recursor.cc

    r1354 r1402  
    6767FDMultiplexer* g_fdm; 
    6868unsigned int g_maxTCPPerClient; 
     69unsigned int g_networkTimeoutMsec; 
    6970bool g_logCommonErrors; 
    7071shared_ptr<PowerDNSLua> g_pdl; 
     
    8586g_tcpListenSockets_t g_tcpListenSockets; 
    8687int g_tcpTimeout; 
     88 
    8789map<int, ComboAddress> g_listenSocketsAddresses; 
    8890struct DNSComboWriter { 
     
    152154  string packet; 
    153155 
    154   int ret=MT->waitEvent(pident, &packet, 1); 
     156  int ret=MT->waitEvent(pident, &packet, g_networkTimeoutMsec); 
    155157 
    156158  if(!ret || ret==-1) { // timeout 
     
    174176  g_fdm->addReadFD(sock->getHandle(), handleTCPClientReadable, pident); 
    175177 
    176   int ret=MT->waitEvent(pident,&data,1); 
     178  int ret=MT->waitEvent(pident, &data, g_networkTimeoutMsec); 
    177179  if(!ret || ret==-1) { // timeout 
    178180    g_fdm->removeReadFD(sock->getHandle()); 
     
    340342  g_fdm->addReadFD(*fd, handleUDPServerResponse, pident); 
    341343  ret=send(*fd, data, len, 0); 
     344  int tmp = errno; 
    342345  if(ret < 0) 
    343346    g_udpclientsocks.returnSocket(*fd); 
     347  errno = tmp; // this is for logging purposes only 
    344348  return ret; 
    345349} 
     
    347351// -1 is error, 0 is timeout, 1 is success 
    348352int arecvfrom(char *data, int len, int flags, const ComboAddress& fromaddr, int *d_len,  
    349               uint16_t id, const string& domain, uint16_t qtype, int fd, unsigned int now) 
     353              uint16_t id, const string& domain, uint16_t qtype, int fd, struct timeval* now) 
    350354{ 
    351355  static optional<unsigned int> nearMissLimit; 
     
    361365 
    362366  string packet; 
    363   int ret=MT->waitEvent(pident, &packet, 1, now); 
     367  int ret=MT->waitEvent(pident, &packet, g_networkTimeoutMsec, now); 
    364368 
    365369  if(ret > 0) { 
     
    18111815  } 
    18121816   
     1817  g_networkTimeoutMsec = ::arg().asNum("network-timeout"); 
    18131818  parseAuthAndForwards(); 
    18141819 
     
    18951900   
    18961901  for(;;) { 
    1897     while(MT->schedule(g_now.tv_sec)); // housekeeping, let threads do their thing 
     1902    while(MT->schedule(&g_now)); // housekeeping, let threads do their thing 
    18981903       
    18991904    if(!(counter%500)) { 
     
    19931998    ::arg().set("setgid","If set, change group id to this gid for more security")=""; 
    19941999    ::arg().set("setuid","If set, change user id to this uid for more security")=""; 
     2000    ::arg().set("network-timeout", "Wait this nummer of milliseconds for network i/o")="1500"; 
    19952001#ifdef WIN32 
    19962002    ::arg().set("quiet","Suppress logging of questions and answers")="off";