From ad252b2c56e784c733257457aec1cab903be61b5 Mon Sep 17 00:00:00 2001 From: Luke Yang Date: Wed, 31 Jul 2024 12:27:59 -0400 Subject: [PATCH] Extend rpm-ostreed.service idle-timeout When making D-Bus calls to the rpm-ostreed.service, the service will always exit after the specified idle-timeout has passed from when the daemon was first created. Even if D-Bus calls are constantly being made, the idle-timeout will still be enforced. This commit subscribes to the bus, listening for new calls. If a call is detected, the idle-timeout is reset. The service will only stop after the idle-timeout has passed after the last call to the bus. Signed-off-by: Luke Yang --- src/daemon/rpmostreed-daemon.cxx | 25 ++++++++++++++++++++++++- src/daemon/rpmostreed-daemon.h | 4 ++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/daemon/rpmostreed-daemon.cxx b/src/daemon/rpmostreed-daemon.cxx index 7a92545198..34410adf7d 100644 --- a/src/daemon/rpmostreed-daemon.cxx +++ b/src/daemon/rpmostreed-daemon.cxx @@ -562,6 +562,20 @@ on_idle_exit (void *data) return FALSE; } +void +reset_idle_exit_timer (GDBusConnection *connection, const gchar *sender_name, + const gchar *object_path, const gchar *interface_name, + const gchar *signal_name, GVariant *parameters, gpointer user_data) +{ + auto self = static_cast (user_data); + if (self->idle_exit_source) + { + guint64 curtime = g_source_get_time (self->idle_exit_source); + const guint idle_exit_secs = self->idle_exit_timeout + g_random_int_range (0, 5); + g_source_set_ready_time (self->idle_exit_source, curtime + idle_exit_secs * G_USEC_PER_SEC); + } +} + static void update_status (RpmostreedDaemon *self) { @@ -571,6 +585,12 @@ update_status (RpmostreedDaemon *self) const guint n_clients = g_hash_table_size (self->bus_clients); gboolean currently_idle = FALSE; + guint subscription_id; + + subscription_id = g_dbus_connection_signal_subscribe ( + self->connection, NULL, NULL, NULL, "/org/freedesktop/DBus", NULL, G_DBUS_SIGNAL_FLAGS_NONE, + reset_idle_exit_timer, g_object_ref (self), g_object_unref); + g_object_get (rpmostreed_sysroot_get (), "active-transaction", &active_txn, NULL); if (active_txn) @@ -618,7 +638,10 @@ update_status (RpmostreedDaemon *self) guint64 curtime = g_source_get_time (self->idle_exit_source); guint64 timeout_micros = readytime - curtime; if (readytime < curtime) - timeout_micros = 0; + { + timeout_micros = 0; + g_dbus_connection_signal_unsubscribe (self->connection, subscription_id); + } g_assert (currently_idle && self->idle_exit_source); sd_notifyf (0, "STATUS=clients=%u; idle exit in %" G_GUINT64_FORMAT " seconds", n_clients, diff --git a/src/daemon/rpmostreed-daemon.h b/src/daemon/rpmostreed-daemon.h index b05743d5be..ba1656a1bd 100644 --- a/src/daemon/rpmostreed-daemon.h +++ b/src/daemon/rpmostreed-daemon.h @@ -68,3 +68,7 @@ namespace rpmostreecxx { rust::Box rpmostreed_daemon_tokio_enter (RpmostreedDaemon *self); } + +void reset_idle_exit_timer (GDBusConnection *connection, const gchar *sender_name, + const gchar *object_path, const gchar *interface_name, + const gchar *signal_name, GVariant *parameters, gpointer user_data);