#include "display.h"
#include "select.h"
+#define MIN_DISPLAY_REDRAW_USEC 100000
+
+static int timeval_after_or_equal(
+ const struct timeval *a,
+ const struct timeval *b)
+{
+ if (a->tv_sec > b->tv_sec)
+ return 1;
+ if (a->tv_sec < b->tv_sec)
+ return 0;
+
+ return a->tv_usec >= b->tv_usec;
+}
+
+static void timeval_add_usec(
+ struct timeval *timeval,
+ int usec)
+{
+ timeval->tv_usec += usec;
+ timeval->tv_sec += timeval->tv_usec / 1000000;
+ timeval->tv_usec %= 1000000;
+}
+
+static void timeval_subtract(
+ struct timeval *result,
+ const struct timeval *end,
+ const struct timeval *start)
+{
+ result->tv_usec = end->tv_usec - start->tv_usec;
+ result->tv_sec = end->tv_sec - start->tv_sec;
+
+ if (result->tv_usec < 0) {
+ --result->tv_sec;
+ result->tv_usec += 1000000;
+ }
+
+ if (result->tv_sec < 0) {
+ result->tv_sec = 0;
+ result->tv_usec = 0;
+ }
+}
+
+static void timeval_min(
+ struct timeval *timeval,
+ const struct timeval *limit)
+{
+ if (timeval_after_or_equal(timeval, limit))
+ *timeval = *limit;
+}
+
void select_loop(
struct mtr_ctl *ctl)
{
int paused = 0;
struct timeval lasttime, thistime, selecttime;
struct timeval startgrace;
+ struct timeval nextredraw;
int dt;
int rv;
int graceperiod = 0;
memset(&startgrace, 0, sizeof(startgrace));
gettimeofday(&lasttime, NULL);
+ nextredraw = lasttime;
while (1) {
dt = calc_deltatime(ctl->WaitTime);
&selecttime);
} else {
- if (ctl->Interactive)
- display_redraw(ctl);
-
gettimeofday(&thistime, NULL);
+ if (ctl->Interactive
+ && timeval_after_or_equal(&thistime, &nextredraw)) {
+ display_redraw(ctl);
+ nextredraw = thistime;
+ timeval_add_usec(&nextredraw, MIN_DISPLAY_REDRAW_USEC);
+ }
+
if (thistime.tv_sec > lasttime.tv_sec + intervaltime.tv_sec
|| (thistime.tv_sec ==
lasttime.tv_sec + intervaltime.tv_sec
}
}
+ if (ctl->Interactive) {
+ struct timeval redrawtime;
+
+ /*
+ * Packet and resolver events must still be handled
+ * immediately; only terminal repainting is capped.
+ */
+ timeval_subtract(&redrawtime, &nextredraw, &thistime);
+ timeval_min(&selecttime, &redrawtime);
+ }
+
rv = select(maxfd, (void *) &readfd, NULL, NULL,
&selecttime);
}