Check expiries when no IO is ready
[khatus.git] / x5 / khatus.c
index e804642..6ffa538 100644 (file)
@@ -316,7 +316,7 @@ opts_parse(Config *cfg, int argc, char *argv[])
 }
 
 void
-fifo_expire_one(Fifo *f, struct timespec t, char *buf)
+fifo_expire(Fifo *f, struct timespec t, char *buf)
 {
        struct timespec td;
 
@@ -328,15 +328,6 @@ fifo_expire_one(Fifo *f, struct timespec t, char *buf)
        }
 }
 
-void
-fifo_expire_all(Config *cfg, struct timespec t, char *buf)
-{
-       Fifo *f;
-
-       for (f = cfg->fifos; f; f = f->next)
-               fifo_expire_one(f, t, buf);
-}
-
 void
 fifo_read_error(Fifo *f, char *buf)
 {
@@ -345,7 +336,7 @@ fifo_read_error(Fifo *f, char *buf)
 
        b = buf + f->pos_init;
        /* Copy as much of the error message as possible.
-        * EXCLUDING the reminating \0. */
+        * EXCLUDING the terminating \0. */
        for (i = 0; i < errlen && i < f->width; i++)
                b[i] = errmsg[i];
        /* Any remaining slots: */
@@ -397,12 +388,13 @@ fifo_read_one(Fifo *f, struct timespec t, char *buf)
 }
 
 void
-fifo_read_all(Config *cfg, struct timespec t, char *buf)
+fifo_read_all(Config *cfg, struct timespec *ti, char *buf)
 {
        fd_set fds;
        int maxfd = -1;
        int ready = 0;
        struct stat st;
+       struct timespec t;
 
        FD_ZERO(&fds);
        for (Fifo *f = cfg->fifos; f; f = f->next) {
@@ -435,13 +427,12 @@ fifo_read_all(Config *cfg, struct timespec t, char *buf)
                FD_SET(f->fd, &fds);
        }
        debug("selecting...\n");
-       ready = select(maxfd + 1, &fds, NULL, NULL, NULL);
+       ready = pselect(maxfd + 1, &fds, NULL, NULL, ti, NULL);
        debug("ready: %d\n", ready);
-       assert(ready != 0);
-       if (ready < 0)
-               /* TODO: Do we really want to fail here? */
-               fatal("%s", strerror(errno));
-       while (ready) {
+       assert(ready >= 0);
+       clock_gettime(CLOCK_MONOTONIC, &t);
+       /* At-least-once ensures that expiries are still checked on timeouts. */
+       do {
                for (Fifo *f = cfg->fifos; f; f = f->next) {
                        if (FD_ISSET(f->fd, &fds)) {
                                debug("reading: %s\n", f->name);
@@ -472,9 +463,11 @@ fifo_read_all(Config *cfg, struct timespec t, char *buf)
                                default:
                                        assert(0);
                                }
+                       } else {
+                               fifo_expire(f, t, buf);
                        }
                }
-       }
+       } while (ready);
        assert(ready == 0);
 }
 
@@ -555,11 +548,7 @@ main(int argc, char *argv[])
        /* TODO: Handle signals */
        for (;;) {
                clock_gettime(CLOCK_MONOTONIC, &t0); // FIXME: check errors
-               /* TODO: Set timeout on fifo_read_all based on diff of last time of
-                *       fifo_read_all and desired time of next TTL check?
-                */
-               /* TODO: How long to wait on IO? Max TTL? */
-               fifo_read_all(cfg, t0, buf);
+               fifo_read_all(cfg, &ti, buf);
                if (cfg->output_to_x_root_window) {
                        if (XStoreName(display, DefaultRootWindow(display), buf) < 0)
                                fatal("XStoreName failed.\n");
@@ -568,14 +557,6 @@ main(int argc, char *argv[])
                        puts(buf);
                        fflush(stdout);
                }
-
-               /*
-                * This is a good place for expiry check, since we're about to
-                * sleep anyway and the time taken by the check will be
-                * subtracted from the sleep period.
-                */
-               fifo_expire_all(cfg, t0, buf);
-
                clock_gettime(CLOCK_MONOTONIC, &t1); // FIXME: check errors
                timespecsub(&t1, &t0, &td);
                debug("td {tv_sec = %ld, tv_nsec = %ld}\n", td.tv_sec, td.tv_nsec);
This page took 0.032009 seconds and 4 git commands to generate.