summaryrefslogtreecommitdiff
path: root/src/login/logind.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2012-05-05 00:34:48 +0200
committerLennart Poettering <lennart@poettering.net>2012-05-05 00:36:08 +0200
commiteecd1362f7f4de432483b5d77c56726c3621a83a (patch)
treee8f1f3639121d317660cc6cc0d5ffe8f8731a39f /src/login/logind.c
parenta26336da875a6657d404d1e44b86ae067c34b110 (diff)
logind: implement delay inhibitor locks in addition to block inhibitor locks
This is useful to allow applications to synchronously save data before the system is suspended or shut down.
Diffstat (limited to 'src/login/logind.c')
-rw-r--r--src/login/logind.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/login/logind.c b/src/login/logind.c
index 6b7012ec73..5860bfc8d7 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -50,6 +50,7 @@ Manager *manager_new(void) {
m->udev_vcsa_fd = -1;
m->epoll_fd = -1;
m->n_autovts = 6;
+ m->inhibit_delay_max = 5 * USEC_PER_SEC;
m->devices = hashmap_new(string_hash_func, string_compare_func);
m->seats = hashmap_new(string_hash_func, string_compare_func);
@@ -1163,7 +1164,7 @@ int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
assert(m);
- idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, t);
+ idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t);
HASHMAP_FOREACH(s, m->sessions, i) {
dual_timestamp k;
@@ -1264,15 +1265,28 @@ int manager_run(Manager *m) {
for (;;) {
struct epoll_event event;
int n;
+ int msec = -1;
manager_gc(m, true);
+ if (manager_dispatch_delayed_shutdown(m) > 0)
+ continue;
+
if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE)
continue;
manager_gc(m, true);
- n = epoll_wait(m->epoll_fd, &event, 1, -1);
+ if (m->delayed_shutdown) {
+ usec_t x, y;
+
+ x = now(CLOCK_MONOTONIC);
+ y = m->delayed_shutdown_timestamp + m->inhibit_delay_max;
+
+ msec = x >= y ? 0 : (int) ((y - x) / USEC_PER_MSEC);
+ }
+
+ n = epoll_wait(m->epoll_fd, &event, 1, msec);
if (n < 0) {
if (errno == EINTR || errno == EAGAIN)
continue;
@@ -1281,6 +1295,9 @@ int manager_run(Manager *m) {
return -errno;
}
+ if (n == 0)
+ continue;
+
switch (event.data.u32) {
case FD_SEAT_UDEV: