}
void
-fifo_expire_one(Fifo *f, struct timespec t, char *buf)
+fifo_expire(Fifo *f, struct timespec t, char *buf)
{
struct timespec td;
}
}
-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)
{
}
void
-fifo_read_all(Config *cfg, char *buf)
+fifo_read_all(Config *cfg, struct timespec *ti, char *buf)
{
fd_set fds;
int maxfd = -1;
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));
clock_gettime(CLOCK_MONOTONIC, &t);
- while (ready) {
+ if (ready == -1) {
+ switch (errno) {
+ case EINTR:
+ error("pselect temp failure: %d, errno: %d, msg: %s\n",
+ ready, errno, strerror(errno));
+ /* TODO: Reconsider what to do here. */
+ return;
+ default:
+ error("pselect failed: %d, errno: %d, msg: %s\n",
+ ready, errno, strerror(errno));
+ }
+ }
+ /* 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);
default:
assert(0);
}
+ } else {
+ fifo_expire(f, t, buf);
}
}
- }
+ } while (ready);
assert(ready == 0);
}
/* 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, 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");
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);