summaryrefslogtreecommitdiff
path: root/src/login
diff options
context:
space:
mode:
authorDaniel Mack <daniel@zonque.org>2015-04-11 18:44:51 +0200
committerDaniel Mack <daniel@zonque.org>2015-04-24 17:48:12 +0200
commitc0f32805086ff65d2905b0e3a9166d9ed6c2bc41 (patch)
tree25490b615512e26dd9b941d309a4ff232b3da14a /src/login
parent3f61a7a6eb5ff7e5a14cd322897741969df6b723 (diff)
logind: use sd_event timer source for inhibitor logic
Instead of open-coding the delayed action and inhibit timeout logic, switch over to a real sd_event_source based implementation. This is not only easier to read but also allows us to add more timers in the future.
Diffstat (limited to 'src/login')
-rw-r--r--src/login/logind-dbus.c98
-rw-r--r--src/login/logind.c17
-rw-r--r--src/login/logind.h4
3 files changed, 62 insertions, 57 deletions
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 037459be71..e8a92db691 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -1459,17 +1459,75 @@ static int execute_shutdown_or_sleep(
return 0;
}
+static int manager_inhibit_timeout_handler(
+ sd_event_source *s,
+ uint64_t usec,
+ void *userdata) {
+
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ Inhibitor *offending = NULL;
+ Manager *manager = userdata;
+ int r;
+
+ assert(manager);
+ assert(manager->inhibit_timeout_source == s);
+
+ if (manager->action_what == 0 || manager->action_job)
+ return 0;
+
+ if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
+ _cleanup_free_ char *comm = NULL, *u = NULL;
+
+ (void) get_process_comm(offending->pid, &comm);
+ u = uid_to_name(offending->uid);
+
+ log_notice("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
+ offending->uid, strna(u),
+ offending->pid, strna(comm));
+ }
+
+ /* Actually do the operation */
+ r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
+ if (r < 0) {
+ log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
+
+ manager->action_unit = NULL;
+ manager->action_what = 0;
+ }
+
+ return 0;
+}
+
static int delay_shutdown_or_sleep(
Manager *m,
InhibitWhat w,
const char *unit_name) {
+ int r;
+ usec_t timeout_val;
+
assert(m);
assert(w >= 0);
assert(w < _INHIBIT_WHAT_MAX);
assert(unit_name);
- m->action_timestamp = now(CLOCK_MONOTONIC);
+ timeout_val = now(CLOCK_MONOTONIC) + m->inhibit_delay_max;
+
+ if (m->inhibit_timeout_source) {
+ r = sd_event_source_set_time(m->inhibit_timeout_source, timeout_val);
+ if (r < 0)
+ return log_error_errno(r, "sd_event_source_set_time() failed: %m\n");
+
+ r = sd_event_source_set_enabled(m->inhibit_timeout_source, SD_EVENT_ONESHOT);
+ if (r < 0)
+ return log_error_errno(r, "sd_event_source_set_enabled() failed: %m\n");
+ } else {
+ r = sd_event_add_time(m->event, &m->inhibit_timeout_source, CLOCK_MONOTONIC,
+ timeout_val, 0, manager_inhibit_timeout_handler, m);
+ if (r < 0)
+ return r;
+ }
+
m->action_unit = unit_name;
m->action_what = w;
@@ -2358,44 +2416,6 @@ int manager_send_changed(Manager *manager, const char *property, ...) {
l);
}
-int manager_dispatch_delayed(Manager *manager) {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- Inhibitor *offending = NULL;
- int r;
-
- assert(manager);
-
- if (manager->action_what == 0 || manager->action_job)
- return 0;
-
- /* Continue delay? */
- if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
- _cleanup_free_ char *comm = NULL, *u = NULL;
-
- get_process_comm(offending->pid, &comm);
- u = uid_to_name(offending->uid);
-
- if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
- return 0;
-
- log_info("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
- offending->uid, strna(u),
- offending->pid, strna(comm));
- }
-
- /* Actually do the operation */
- r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
- if (r < 0) {
- log_warning("Failed to send delayed message: %s", bus_error_message(&error, r));
-
- manager->action_unit = NULL;
- manager->action_what = 0;
- return r;
- }
-
- return 1;
-}
-
int manager_start_scope(
Manager *manager,
const char *scope,
diff --git a/src/login/logind.c b/src/login/logind.c
index 707d528fbb..ea7c6e74b0 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -141,6 +141,7 @@ void manager_free(Manager *m) {
set_free_free(m->busnames);
sd_event_source_unref(m->idle_action_event_source);
+ sd_event_source_unref(m->inhibit_timeout_source);
sd_event_source_unref(m->console_active_event_source);
sd_event_source_unref(m->udev_seat_event_source);
@@ -1093,8 +1094,6 @@ int manager_run(Manager *m) {
assert(m);
for (;;) {
- usec_t us = (uint64_t) -1;
-
r = sd_event_get_state(m->event);
if (r < 0)
return r;
@@ -1103,19 +1102,7 @@ int manager_run(Manager *m) {
manager_gc(m, true);
- if (manager_dispatch_delayed(m) > 0)
- continue;
-
- if (m->action_what != 0 && !m->action_job) {
- usec_t x, y;
-
- x = now(CLOCK_MONOTONIC);
- y = m->action_timestamp + m->inhibit_delay_max;
-
- us = x >= y ? 0 : y - x;
- }
-
- r = sd_event_run(m->event, us);
+ r = sd_event_run(m->event, (uint64_t) -1);
if (r < 0)
return r;
}
diff --git a/src/login/logind.h b/src/login/logind.h
index 4781688f0a..caf78f734a 100644
--- a/src/login/logind.h
+++ b/src/login/logind.h
@@ -95,7 +95,7 @@ struct Manager {
/* If a shutdown/suspend is currently executed, then this is
* the job of it */
char *action_job;
- usec_t action_timestamp;
+ sd_event_source *inhibit_timeout_source;
sd_event_source *idle_action_event_source;
usec_t idle_action_usec;
@@ -167,8 +167,6 @@ int bus_manager_shutdown_or_sleep_now_or_later(Manager *m, const char *unit_name
int manager_send_changed(Manager *manager, const char *property, ...) _sentinel_;
-int manager_dispatch_delayed(Manager *manager);
-
int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, const char *after, const char *after2, sd_bus_error *error, char **job);
int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);