mirror of
https://gitlab.freedesktop.org/upower/upower.git
synced 2026-04-20 04:50:48 +02:00
linux: Use inhibitor lock to guard poll pausing
Use an inhibitor lock obtained via logind to make sure the polling is paused before the system is put to sleep, rather than racing with the suspension. https://bugs.freedesktop.org/show_bug.cgi?id=99763
This commit is contained in:
parent
01cd65c1a7
commit
09cdb0ccfc
2 changed files with 86 additions and 1 deletions
|
|
@ -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) \
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
@ -460,6 +462,78 @@ up_backend_take_action (UpBackend *backend)
|
|||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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:
|
||||
*
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue