logind: Always send ping if data is queued

sd_bus_call_method may have read and queued our ping response, so we
cannot assume that a previous ping will make the socket readable.

Instead, always send a ping if read or write queues are not empty, even
if a ping has already been sent.
This commit is contained in:
Kenny Levinsen 2022-02-15 13:24:41 +01:00
parent b47c79d731
commit f128359332

View file

@ -41,7 +41,6 @@ struct backend_logind {
bool active; bool active;
bool initial_setup; bool initial_setup;
bool awaiting_pong;
int has_drm; int has_drm;
}; };
@ -70,13 +69,12 @@ static int close_seat(struct libseat *base) {
static int ping_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { static int ping_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
(void)ret_error; (void)ret_error;
struct backend_logind *session = userdata; (void)userdata;
if (sd_bus_message_is_method_error(m, NULL)) { if (sd_bus_message_is_method_error(m, NULL)) {
const sd_bus_error *error = sd_bus_message_get_error(m); const sd_bus_error *error = sd_bus_message_get_error(m);
log_errorf("Ping failed: %s: %s", error->name, error->message); log_errorf("Ping failed: %s: %s", error->name, error->message);
return -1; return -1;
} }
session->awaiting_pong = false;
return 0; return 0;
} }
@ -91,14 +89,15 @@ static int send_ping(struct backend_logind *backend) {
} }
static void check_pending_events(struct backend_logind *backend) { static void check_pending_events(struct backend_logind *backend) {
if (sd_bus_get_events(backend->bus) <= 0) { uint64_t queued_read, queued_write;
return; sd_bus_get_n_queued_read(backend->bus, &queued_read);
} sd_bus_get_n_queued_write(backend->bus, &queued_write);
if (backend->awaiting_pong) {
if (queued_read == 0 && queued_write == 0) {
return; return;
} }
// We have events pending execution, so a dispatch is required. // The sd_bus instance has queued data, so a dispatch is required.
// However, we likely already drained our socket, so there will not be // However, we likely already drained our socket, so there will not be
// anything to read. Instead, send a ping request to logind so that the // anything to read. Instead, send a ping request to logind so that the
// user will be woken up by its response. // user will be woken up by its response.
@ -107,7 +106,6 @@ static void check_pending_events(struct backend_logind *backend) {
log_errorf("Could not send ping message: %s", strerror(-ret)); log_errorf("Could not send ping message: %s", strerror(-ret));
return; return;
} }
backend->awaiting_pong = true;
} }
static int open_device(struct libseat *base, const char *path, int *fd) { static int open_device(struct libseat *base, const char *path, int *fd) {
@ -286,6 +284,7 @@ static int dispatch_and_execute(struct libseat *base, int timeout) {
total_dispatched += dispatched; total_dispatched += dispatched;
} }
} }
check_pending_events(backend);
return total_dispatched; return total_dispatched;
} }
@ -742,6 +741,7 @@ static struct libseat *logind_open_seat(const struct libseat_seat_listener *list
backend->seat_listener_data = data; backend->seat_listener_data = data;
backend->base.impl = &logind_impl; backend->base.impl = &logind_impl;
check_pending_events(backend);
return &backend->base; return &backend->base;
error: error: