From 4380235b19d99996ad91d858a74303a4f37751d0 Mon Sep 17 00:00:00 2001 From: gretchen Date: Mon, 18 Nov 2019 17:45:13 -0800 Subject: Simplify timespec handling; timeout. --- norns_shell.c | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/norns_shell.c b/norns_shell.c index 10f10b0..386596e 100644 --- a/norns_shell.c +++ b/norns_shell.c @@ -11,6 +11,23 @@ #define MAX_LINE 1024 +#define S(n) (1000000000 * ((long) n)) +#define MS(n) (1000000 * ((long) n)) + +#define SENTINEL_TIMEOUT (MS(1500)) +#define SENTINEL_DELAY (MS(200)) + +int timespec_diff_gt(struct timespec *before, struct timespec *after, long ns) +{ + /* be careful not to overflow the long... */ + long ss = ns / S(1) + 1; + long ss_diff = after->tv_sec - before->tv_sec; + if (ss_diff > ss) + return 1; + long ns_diff = ss_diff * S(1) + (after->tv_nsec - before->tv_nsec); + return ns_diff > ns; +} + int killed = 0; void handle_signal(int sig_num) { @@ -85,8 +102,12 @@ int main (int argc, char **argv) -- as a sentinel -- repeatedly until we get the corresponding . */ - /* TODO: time out after three seconds or something. */ int received = 0; + struct timespec began = {0}; + if (clock_gettime(CLOCK_MONOTONIC, &began)) { + fprintf(stderr, "Can't use the clock? %m\n"); + goto error; + } struct timespec sent_sentinel = {0}; /* we'll also wait for one message after EOF... */ @@ -131,16 +152,25 @@ int main (int argc, char **argv) /* If we can write, see if there's a full line. */ if (poll_s.revents & NN_POLLOUT) { if (!received) { - /* only do this five times a second... */ struct timespec now = {0}; if (clock_gettime(CLOCK_MONOTONIC, &now)) { fprintf(stderr, "Can't use the clock? %m\n"); goto error; } - /* first bit syncs with the clock... */ - if ((now.tv_sec - sent_sentinel.tv_sec <= 1) - && (now.tv_nsec - sent_sentinel.tv_nsec - <= (1000000000 / 5))) + /* if we've been waiting on sentinel response and + haven't gotten anything, time out. */ + if (timespec_diff_gt(&began, &now, SENTINEL_TIMEOUT)) { + fprintf(stderr, + "# timed out.\n" + "# are you sure there's something " + "listening at %s?\n", + endpoint); + goto error; + } + /* only do this once every SENTINEL_DELAY... */ + if (!timespec_diff_gt(&sent_sentinel, + &now, + SENTINEL_DELAY)) break; memcpy(&sent_sentinel, &now, sizeof(struct timespec)); -- cgit v1.2.1