From e38bc7a7608a88137eda2daa5664b43ece451928 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 27 Nov 2018 10:45:57 +1000 Subject: [PATCH] ratbagd: set up a simple exit-on-idle ratbagd is not something that needs stay around forever just because we configured a mouse once. We have DBus activation and we don't store anything anyway, so we might as well exit after a period of inactivity (20 min). There's a slight race condition where if something comes in at exactly the 20min mark, we may shut down anyway and the messages get lost. This is too narrow to worry about. Signed-off-by: Peter Hutterer --- ratbagd/ratbagd.c | 50 +++++++++++++++++++++++++++++++++++------------ ratbagd/ratbagd.h | 1 + 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/ratbagd/ratbagd.c b/ratbagd/ratbagd.c index 1e4815d4..61a83303 100644 --- a/ratbagd/ratbagd.c +++ b/ratbagd/ratbagd.c @@ -489,6 +489,26 @@ exit: return r; } +static int on_timeout_cb(sd_event_source *s, uint64_t usec, void *userdata) +{ + log_info("Exiting after idle\n"); + sd_event_exit(sd_event_source_get_event(s), 0); + return 0; +} + +static int before_idle_cb(sd_event_source *s, void *userdata) +{ + struct ratbagd *ctx = userdata; + uint64_t usec; + + sd_event_now(sd_event_source_get_event(s), CLOCK_MONOTONIC, &usec); +#define min2us(us_) (us_ * 1000000 * 60) + usec += min2us(20); + sd_event_source_set_time(ctx->timeout_source, usec); + + return 0; +} + static int sighandler(sd_event_source *source, const struct signalfd_siginfo *si, void *userdata) @@ -502,18 +522,6 @@ static int ratbagd_run(struct ratbagd *ctx) { int r; - /* - * TODO: We should support exit-on-idle and bus-activation. Note that - * we don't store any state on our own, hence, all we have to do - * is to make sure we advertise device add/remove events via the - * bus (in case there is a listener). - * To track such events, we should store devices we already - * advertised in /run/ratbagd/devices/ and read it out on - * activation. - * Note that this feature requires udev-activation, which might - * not be possible, yet. - */ - r = ratbagd_run_enumerate(ctx); if (r < 0) return r; @@ -524,6 +532,24 @@ static int ratbagd_run(struct ratbagd *ctx) sigprocmask(SIG_BLOCK, &sigset, NULL); sd_event_add_signal(ctx->event, NULL, SIGINT, sighandler, NULL); + /* exit-on-idle: we set up a timer to simply exit. Since we don't + * store anything, it doesn't matter and we can just restart next + * time someone wants us. + * + * since we don't want to monitor every single dbus call, we just + * set up a post source that gets called before we go idle. That + * resets the timer, so as long as something is happening, ratbagd + * won't exit. + */ + sd_event_add_time(ctx->event, + &ctx->timeout_source, + CLOCK_MONOTONIC, + -1, /* infinite, see before_idle_cb */ + min2us(1), /* accuracy doesn't matter */ + on_timeout_cb, + ctx); + sd_event_add_post(ctx->event, NULL, before_idle_cb, ctx); + return sd_event_loop(ctx->event); } diff --git a/ratbagd/ratbagd.h b/ratbagd/ratbagd.h index 04311b36..5c91e2eb 100644 --- a/ratbagd/ratbagd.h +++ b/ratbagd/ratbagd.h @@ -208,6 +208,7 @@ struct ratbagd { sd_event *event; struct ratbag *lib_ctx; struct udev_monitor *monitor; + sd_event_source *timeout_source; sd_event_source *monitor_source; sd_bus *bus;