chiark / gitweb /
Take advantage of sigtimedwait().
authorBen Harris <bjh21@bjh21.me.uk>
Fri, 23 Nov 2018 21:27:47 +0000 (21:27 +0000)
committerBen Harris <bjh21@bjh21.me.uk>
Sat, 8 Dec 2018 22:30:09 +0000 (22:30 +0000)
This saves the need for two separate timers, since the sigtimedwait()
timeout can serve the purpose of the fallback timer.

clunk.c

diff --git a/clunk.c b/clunk.c
index 8fa0d19d9f39b710b74b212ddeee7ab71389544b..7f10dc9ad61337ba63e6b664ab5e503213e4fe99 100644 (file)
--- a/clunk.c
+++ b/clunk.c
@@ -37,12 +37,7 @@ static char statebuf[10];
 
 static sigset_t signals_to_block, timing_signals;
 
-/*
- * The fallback timer protects us from occasions when CLOCK_REALTIME
- * goes backwards so our nice absolute clock_nanosleep() end up
- * sleeping far too long.
- */
-static timer_t main_timer, fallback_timer;
+static timer_t main_timer;
 
 static void
 dummy_out(bool state)
@@ -202,8 +197,6 @@ init(int argc, char **argv)
                err(1, "sigprocmask");
        if (timer_create(CLOCK_REALTIME, &sev, &main_timer) != 0)
                err(1, "timer_create");
-       if (timer_create(CLOCK_MONOTONIC, &sev, &fallback_timer) != 0)
-               err(1, "timer_create");
 
        if (clock_gettime(CLOCK_REALTIME, &ts) != 0)
                err(1, "clock_gettime");
@@ -263,13 +256,10 @@ run()
        struct itimerspec its_main = {
                .it_interval = { .tv_sec = 0, .tv_nsec = 0}
        };
-       const struct itimerspec its_fallback = {
-               .it_value    = { .tv_sec = 35, .tv_nsec = 0},
-               .it_interval = { .tv_sec = 0,  .tv_nsec = 0},
-       };
        const struct itimerspec its_disarm = {
                .it_value =  { .tv_sec = 0, .tv_nsec = 0 },
        };
+       struct timespec const timeout = { .tv_sec = 31, .tv_nsec = 0 };
        struct tm tm;
        int tick;
        sigset_t pending_signals;
@@ -302,22 +292,22 @@ run()
                if (timer_settime(main_timer, TIMER_ABSTIME, &its_main, NULL)
                    != 0)
                        err(1, "timer_settime (arm main)");
-               if (timer_settime(fallback_timer, 0, &its_fallback, NULL) != 0)
-                       err(1, "timer_settime (arm fallback)");
-               errno = sigwait(&timing_signals, &signo);
-               if (errno != 0)
-                       err(1, "sigwait");
-               if (timer_settime(main_timer, 0, &its_disarm, NULL) != 0)
-                       err(1, "timer_settime (disarm)");
-               if (timer_settime(fallback_timer, 0, &its_disarm, NULL) != 0)
-                       err(1, "timer_settime (disarm)");
-               /* Clear any pending SIGALRM */
-               if (sigpending(&pending_signals) == -1)
-                       err(1, "sigpending");
-               if (sigismember(&pending_signals, SIGALRM)) {
-                       errno = sigwait(&timing_signals, &signo);
-                       if (errno != 0)
-                               err(1, "sigwait");
+               if (sigtimedwait(&timing_signals, NULL, &timeout) == -1) {
+                       if (errno != EAGAIN)
+                               err(1, "sigtimedwait");
+                       /* Fallback timeout expired. */
+                       /* Disarm the main timer. */
+                       if (timer_settime(main_timer, 0,
+                                         &its_disarm, NULL) != 0)
+                               err(1, "timer_settime (disarm)");
+                       /* Clear any pending SIGALRM. */
+                       if (sigpending(&pending_signals) == -1)
+                               err(1, "sigpending");
+                       if (sigismember(&pending_signals, SIGALRM)) {
+                               errno = sigwait(&timing_signals, &signo);
+                               if (errno != 0)
+                                       err(1, "sigwait");
+                       }
                }
        }
 }