--- embedaddon/mtr/select.c 2013/07/21 23:43:41 1.1.1.1 +++ embedaddon/mtr/select.c 2016/11/01 09:33:48 1.1.1.2 @@ -16,7 +16,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include +#include "config.h" + #include #include #include @@ -29,12 +30,10 @@ #include #include "mtr.h" -#include "display.h" #include "dns.h" #include "net.h" -#ifndef NO_IPINFO #include "asn.h" -#endif +#include "display.h" extern int Interactive; extern int MaxPing; @@ -47,6 +46,8 @@ static struct timeval intervaltime; int display_offset = 0; +#define GRACETIME (5 * 1000*1000) + void select_loop(void) { fd_set readfd; fd_set writefd; @@ -59,9 +60,13 @@ void select_loop(void) { int NumPing = 0; int paused = 0; struct timeval lasttime, thistime, selecttime; + struct timeval startgrace; int dt; int rv; + int graceperiod = 0; + memset(&startgrace, 0, sizeof(startgrace)); + gettimeofday(&lasttime, NULL); while(1) { @@ -82,8 +87,12 @@ void select_loop(void) { #ifdef ENABLE_IPV6 if (dns) { dnsfd6 = dns_waitfd6(); - FD_SET(dnsfd6, &readfd); - if(dnsfd6 >= maxfd) maxfd = dnsfd6 + 1; + if (dnsfd6 >= 0) { + FD_SET(dnsfd6, &readfd); + if(dnsfd6 >= maxfd) maxfd = dnsfd6 + 1; + } else { + dnsfd6 = 0; + } } else dnsfd6 = 0; #endif @@ -103,8 +112,13 @@ void select_loop(void) { do { if(anyset || paused) { + /* Set timeout to 0.1s. + * While this is almost instantaneous for human operators, + * it's slow enough for computers to go do something else; + * this prevents mtr from hogging 100% CPU time on one core. + */ selecttime.tv_sec = 0; - selecttime.tv_usec = 0; + selecttime.tv_usec = paused?100000:0; rv = select(maxfd, (void *)&readfd, &writefd, NULL, &selecttime); @@ -117,10 +131,24 @@ void select_loop(void) { (thistime.tv_sec == lasttime.tv_sec + intervaltime.tv_sec && thistime.tv_usec >= lasttime.tv_usec + intervaltime.tv_usec)) { lasttime = thistime; - if(NumPing >= MaxPing && (!Interactive || ForceMaxPing)) + + if (!graceperiod) { + if (NumPing >= MaxPing && (!Interactive || ForceMaxPing)) { + graceperiod = 1; + startgrace = thistime; + } + + /* do not send out batch when we've already initiated grace period */ + if (!graceperiod && net_send_batch()) + NumPing++; + } + } + + if (graceperiod) { + dt = (thistime.tv_usec - startgrace.tv_usec) + + 1000000 * (thistime.tv_sec - startgrace.tv_sec); + if (dt > GRACETIME) return; - if (net_send_batch()) - NumPing++; } selecttime.tv_usec = (thistime.tv_usec - lasttime.tv_usec); @@ -169,12 +197,12 @@ void select_loop(void) { /* Have we finished a nameservice lookup? */ #ifdef ENABLE_IPV6 - if(dns && FD_ISSET(dnsfd6, &readfd)) { + if(dns && dnsfd6 && FD_ISSET(dnsfd6, &readfd)) { dns_ack6(); anyset = 1; } #endif - if(dns && FD_ISSET(dnsfd, &readfd)) { + if(dns && dnsfd && FD_ISSET(dnsfd, &readfd)) { dns_ack(); anyset = 1; } @@ -210,7 +238,7 @@ void select_loop(void) { display_clear(); } break; -#ifndef NO_IPINFO +#ifdef IPINFO case ActionII: if (ipinfo_no >= 0) { ipinfo_no++;