module/clock: internally use either minutes or seconds granularity

This commit is contained in:
Daniel Eklöf 2020-09-24 14:32:39 +02:00
parent a041b8f971
commit 318965b715
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F

View file

@ -4,7 +4,10 @@
#include <assert.h>
#include <poll.h>
#include <sys/time.h>
#define LOG_MODULE "clock"
#include "../log.h"
#include "../bar/bar.h"
#include "../config.h"
#include "../config-verify.h"
@ -12,6 +15,10 @@
struct private {
struct particle *label;
enum {
UPDATE_GRANULARITY_SECONDS,
UPDATE_GRANULARITY_MINUTES,
} update_granularity;
char *date_format;
char *time_format;
};
@ -55,20 +62,56 @@ content(struct module *mod)
static int
run(struct module *mod)
{
const struct private *m = mod->private;
const struct bar *bar = mod->bar;
bar->refresh(bar);
while (true) {
time_t now = time(NULL);
time_t now_no_secs = now / 60 * 60;
assert(now_no_secs % 60 == 0);
struct timespec _now;
clock_gettime(CLOCK_REALTIME, &_now);
time_t next_min = now_no_secs + 60;
time_t timeout = next_min - now;
assert(timeout >= 0 && timeout <= 60);
const struct timeval now = {
.tv_sec = _now.tv_sec,
.tv_usec = _now.tv_nsec / 1000,
};
int timeout_ms;
switch (m->update_granularity) {
case UPDATE_GRANULARITY_SECONDS: {
const struct timeval next_second = {
.tv_sec = now.tv_sec + 1,
.tv_usec = 0};
struct timeval _timeout;
timersub(&next_second, &now, &_timeout);
assert(_timeout.tv_sec == 0 ||
(_timeout.tv_sec == 1 && _timeout.tv_usec == 0));
timeout_ms = _timeout.tv_usec / 1000;
break;
}
case UPDATE_GRANULARITY_MINUTES: {
const struct timeval next_minute = {
.tv_sec = now.tv_sec / 60 * 60 + 60,
.tv_usec = 0,
};
struct timeval _timeout;
timersub(&next_minute, &now, &_timeout);
timeout_ms = _timeout.tv_sec * 1000 + _timeout.tv_usec / 1000;
}
}
/* Add 1ms to account for rounding errors */
timeout_ms++;
LOG_DBG("now: %lds %ldµs -> timeout: %dms",
now.tv_sec, now.tv_usec, timeout_ms);
struct pollfd fds[] = {{.fd = mod->abort_fd, .events = POLLIN}};
poll(fds, 1, timeout * 1000);
poll(fds, 1, timeout_ms);
if (fds[0].revents & POLLIN)
break;
@ -86,6 +129,7 @@ clock_new(struct particle *label, const char *date_format, const char *time_form
m->label = label;
m->date_format = strdup(date_format);
m->time_format = strdup(time_format);
m->update_granularity = UPDATE_GRANULARITY_MINUTES;
struct module *mod = module_common_new();
mod->private = m;