From 417c65cea5e2aa8c1c23549b38183c98612b1b24 Mon Sep 17 00:00:00 2001 From: Jonas Holmberg Date: Tue, 11 Dec 2018 17:45:36 +0100 Subject: [PATCH] Fix #106: Patch timer nsec handling When using timers, a small window exists where they can end up in a non running state. This is caused by how the nsec value in struct timespec is handled when restarting the timers. When a timer is less than a second from expiring it is not restarted correctly, resulting in timers that never expire. Signed-off-by: Jonas Holmberg Signed-off-by: Joachim Nilsson --- src/timer.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/timer.c b/src/timer.c index 7ddbbd0d..3d0f0b38 100644 --- a/src/timer.c +++ b/src/timer.c @@ -58,10 +58,13 @@ static void set(struct timer *t, struct timespec *now) static int expired(struct timer *t, struct timespec *now) { + long round_nsec = now->tv_nsec + 250000000; + round_nsec = round_nsec > 999999999 ? 999999999 : round_nsec; + if (t->timeout.tv_sec < now->tv_sec) return 1; - if (t->timeout.tv_sec == now->tv_sec && t->timeout.tv_nsec <= now->tv_nsec) + if (t->timeout.tv_sec == now->tv_sec && t->timeout.tv_nsec <= round_nsec) return 1; return 0; @@ -108,7 +111,7 @@ static int start(struct timespec *now) memset(&it, 0, sizeof(it)); it.it_value.tv_sec = next->timeout.tv_sec - now->tv_sec; - it.it_value.tv_nsec = 0; + it.it_value.tv_nsec = next->timeout.tv_nsec - now->tv_nsec; timer_settime(timer, 0, &it, NULL); return 0;