summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/linux/Makefile.am5
-rw-r--r--src/linux/up-backend.c82
2 files changed, 86 insertions, 1 deletions
diff --git a/src/linux/Makefile.am b/src/linux/Makefile.am
index e92bdd5..139fdad 100644
--- a/src/linux/Makefile.am
+++ b/src/linux/Makefile.am
@@ -9,6 +9,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/libupower-glib \
$(USB_CFLAGS) \
$(GIO_CFLAGS) \
+ $(GIO_UNIX_CFLAGS) \
$(GUDEV_CFLAGS) \
$(POLKIT_CFLAGS) \
$(GLIB_CFLAGS) \
@@ -56,7 +57,9 @@ hidpp_test_SOURCES = \
hidpp_test_LDADD = \
-lm \
$(GLIB_LIBS) \
- $(GIO_LIBS)
+ $(GIO_LIBS) \
+ $(GIO_UNIX_LIBS)
+
hidpp_test_CFLAGS = $(AM_CFLAGS) $(WARNINGFLAGS_C)
EXTRA_DIST = $(libupshared_la_SOURCES) \
diff --git a/src/linux/up-backend.c b/src/linux/up-backend.c
index edd7775..c5f8fd9 100644
--- a/src/linux/up-backend.c
+++ b/src/linux/up-backend.c
@@ -27,6 +27,7 @@
#include <sys/wait.h>
#include <glib/gi18n.h>
#include <gio/gio.h>
+#include <gio/gunixfdlist.h>
#include <gudev/gudev.h>
#include "up-backend.h"
@@ -63,6 +64,7 @@ struct UpBackendPrivate
UpConfig *config;
GDBusProxy *logind_proxy;
guint logind_sleep_id;
+ int logind_inhibitor_fd;
};
enum {
@@ -461,6 +463,78 @@ up_backend_take_action (UpBackend *backend)
}
/**
+ * up_backend_inhibitor_lock_take:
+ * @backend: The %UpBackend class instance
+ *
+ * Acquire a sleep 'delay lock' via systemd's logind that will
+ * inhibit going to sleep until the lock is released again via
+ * up_backend_inhibitor_lock_release().
+ * Does nothing if the lock was already acquired.
+ */
+static void
+up_backend_inhibitor_lock_take (UpBackend *backend)
+{
+ GVariant *out, *input;
+ GUnixFDList *fds;
+ GError *error = NULL;
+
+ if (backend->priv->logind_inhibitor_fd > -1) {
+ return;
+ }
+
+ input = g_variant_new ("(ssss)",
+ "sleep", /* what */
+ "UPower", /* who */
+ "Pause device polling", /* why */
+ "delay"); /* mode */
+
+ out = g_dbus_proxy_call_with_unix_fd_list_sync (backend->priv->logind_proxy,
+ "Inhibit",
+ input,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &fds,
+ NULL,
+ &error);
+ if (out == NULL) {
+ g_warning ("Could not acquire inhibitor lock: %s", error->message);
+ return;
+ }
+
+ if (g_unix_fd_list_get_length (fds) != 1) {
+ g_warning ("Unexpected values returned by logind's 'Inhibit'");
+ g_variant_unref (out);
+ return;
+ }
+
+ backend->priv->logind_inhibitor_fd = g_unix_fd_list_get (fds, 0, NULL);
+ g_variant_unref (out);
+
+ g_debug ("Acquired inhibitor lock (%i)", backend->priv->logind_inhibitor_fd);
+}
+
+/**
+ * up_backend_inhibitor_lock_release:
+ * @backend: The %UpBackend class instance
+ *
+ * Releases a previously acquired inhibitor lock or does nothing
+ * if no lock is held;
+ */
+static void
+up_backend_inhibitor_lock_release (UpBackend *backend)
+{
+ if (backend->priv->logind_inhibitor_fd == -1) {
+ return;
+ }
+
+ close (backend->priv->logind_inhibitor_fd);
+ backend->priv->logind_inhibitor_fd = -1;
+
+ g_debug ("Released inhibitor lock");
+}
+
+/**
* up_backend_prepare_for_sleep:
*
* Callback for logind's PrepareForSleep signal. It receives
@@ -493,9 +567,12 @@ up_backend_prepare_for_sleep (GDBusConnection *connection,
if (will_sleep) {
up_daemon_pause_poll (backend->priv->daemon);
+ up_backend_inhibitor_lock_release (backend);
return;
}
+ up_backend_inhibitor_lock_take (backend);
+
/* we are waking up, lets refresh all battery devices */
g_debug ("Woke up from sleep; about to refresh devices");
array = up_device_list_get_array (backend->priv->device_list);
@@ -570,6 +647,9 @@ up_backend_init (UpBackend *backend)
backend,
NULL);
backend->priv->logind_sleep_id = sleep_id;
+ backend->priv->logind_inhibitor_fd = -1;
+
+ up_backend_inhibitor_lock_take (backend);
}
/**
@@ -597,6 +677,8 @@ up_backend_finalize (GObject *object)
g_dbus_connection_signal_unsubscribe (bus,
backend->priv->logind_sleep_id);
+ up_backend_inhibitor_lock_release (backend);
+
g_clear_object (&backend->priv->logind_proxy);
g_object_unref (backend->priv->managed_devices);