ports/contrib (3.6): [notify] seatd: includes a patch that could cause the session to fail
commit 7d7362e5ec9dd2efc8036233a35faf79f759cd9d Author: Tim Biermann <tbier@posteo.de> Date: Tue Sep 28 21:52:46 2021 +0200 [notify] seatd: includes a patch that could cause the session to fail diff --git a/seatd/.signature b/seatd/.signature index f0d9fa7b4..cf244e0d4 100644 --- a/seatd/.signature +++ b/seatd/.signature @@ -1,6 +1,7 @@ untrusted comment: verify with /etc/ports/contrib.pub -RWSagIOpLGJF36Smb1uIrwdifvd1VfKZqtKBCWmvS2o93QkUiF5Z9/k0jEM7EtAlQr+fEM/gR+z0FpMNYxgDPK8ONLWiGvKQIAA= -SHA256 (Pkgfile) = f9e165dc464282e3f55115a334a8a93175fd35d59b44fc9a1c7a2401b3f67a14 +RWSagIOpLGJF39+3lUcKSkpHKHbGfwgqOKnOHJHbqTVAq1ZXcVtJLHDbNxysapcSOPgi7JU+5gF6KXze5Nn/RTpoeNjRFS7ZQgg= +SHA256 (Pkgfile) = 2b5f99f6b553861197de4e92e6854ba499dba803177a6a4514184bc11b67eb46 SHA256 (.footprint) = 53478c164d996ba869bccf52a85204378233aa37908ddaa9a6c76e760de6faf8 SHA256 (seatd-0.6.2.tar.gz) = 1e2745ea39266de40d5beb24011782da95468b81ecfa410dd0db5ff75c665727 SHA256 (seatd.service) = 1cc6ff63f8d2b11aa6108f650643b972fcb1bb6bf960b65b78be2aeafdfa282d +SHA256 (vt.patch) = 9e3f8bbff6412cf8744eea143331c09202d804ca3c99326ab6729a517c5093b3 diff --git a/seatd/Pkgfile b/seatd/Pkgfile index 85d00de54..19f1824fe 100644 --- a/seatd/Pkgfile +++ b/seatd/Pkgfile @@ -5,11 +5,14 @@ name=seatd version=0.6.2 -release=1 +release=2 source=(https://github.com/kennylevinsen/seatd/archive/$version/$name-$version.tar.g... - seatd.service) + seatd.service + vt.patch) build() { + patch -Np1 -d $name-$version -i $SRC/vt.patch + meson setup $name-$version build \ --prefix=/usr \ --buildtype=plain \ diff --git a/seatd/vt.patch b/seatd/vt.patch new file mode 100644 index 000000000..910e47679 --- /dev/null +++ b/seatd/vt.patch @@ -0,0 +1,186 @@ +From 2eee9aa445e3f9dc6a7ca115489f87b10f60b9ba Mon Sep 17 00:00:00 2001 +From: Kenny Levinsen <kl@kl.wtf> +Date: Mon, 20 Sep 2021 23:43:10 +0200 +Subject: [PATCH] seatd: Implement ping request to wake up later + +When device open or close messages are sent to seatd, libseat must read +messages from the socket until it sees the associated response message. +This means that it may drain enable/disable seat events from the socket, +queueing them internally for deferred processing. + +As the socket is drained, the caller will not wake from a poll and have +no reason to dispatch libseat. To ensure that these messages would not +be left in the queue, 6fa82930d0c5660eea3102989c765dc864514e36 made it +so that open/close calls would execute all queued events just before +returning. + +Unfortunately, this had the side-effect of having events fire from the +stack of libseat_open_device or libseat_close_device, which we now see +cause problems in compositors. Specifically, an issue has been observed +where libinput end up calling libseat_close_device, which in turn +dispatch a disable seat event that calls libinput_suspend. libinput does +not like this. + +Instead, remove the execution from libseat_open_device and +libseat_close_device, and instead make a "ping" request to seatd if +events have been queued. The response to this will wake us up and ensure +that dispatch is called. +--- + include/protocol.h | 2 ++ + libseat/backend/seatd.c | 45 +++++++++++++++++++++++++++++++++++++---- + seatd/client.c | 22 ++++++++++++++++++++ + 3 files changed, 65 insertions(+), 4 deletions(-) + +diff --git a/include/protocol.h b/include/protocol.h +index b3361ba..cb994fc 100644 +--- a/include/protocol.h ++++ b/include/protocol.h +@@ -15,6 +15,7 @@ + #define CLIENT_CLOSE_DEVICE CLIENT_EVENT(4) + #define CLIENT_DISABLE_SEAT CLIENT_EVENT(5) + #define CLIENT_SWITCH_SESSION CLIENT_EVENT(6) ++#define CLIENT_PING CLIENT_EVENT(7) + + #define SERVER_SEAT_OPENED SERVER_EVENT(1) + #define SERVER_SEAT_CLOSED SERVER_EVENT(2) +@@ -22,6 +23,7 @@ + #define SERVER_DEVICE_CLOSED SERVER_EVENT(4) + #define SERVER_DISABLE_SEAT SERVER_EVENT(5) + #define SERVER_ENABLE_SEAT SERVER_EVENT(6) ++#define SERVER_PONG SERVER_EVENT(7) + #define SERVER_ERROR SERVER_EVENT(0x7FFF) + + #include <stdint.h> +diff --git a/libseat/backend/seatd.c b/libseat/backend/seatd.c +index 85df9f5..26308d1 100644 +--- a/libseat/backend/seatd.c ++++ b/libseat/backend/seatd.c +@@ -36,6 +36,7 @@ struct backend_seatd { + const struct libseat_seat_listener *seat_listener; + void *seat_listener_data; + struct linked_list pending_events; ++ bool awaiting_pong; + bool error; + + char seat_name[MAX_SEAT_LEN]; +@@ -243,6 +244,12 @@ static int dispatch_pending(struct backend_seatd *backend, int *opcode) { + while (connection_get(&backend->connection, &header, sizeof header) != -1) { + packets++; + switch (header.opcode) { ++ case SERVER_PONG: ++ // We care about whether or not the answer has been ++ // read from the connection, so handle it here instead ++ // of pushing it to the pending event list. ++ backend->awaiting_pong = false; ++ break; + case SERVER_DISABLE_SEAT: + case SERVER_ENABLE_SEAT: + if (queue_event(backend, header.opcode) == -1) { +@@ -450,6 +457,36 @@ static const char *seat_name(struct libseat *base) { + return backend->seat_name; + } + ++static int send_ping(struct backend_seatd *backend) { ++ struct proto_header header = { ++ .opcode = CLIENT_PING, ++ .size = 0, ++ }; ++ if (conn_put(backend, &header, sizeof header) == -1 || conn_flush(backend) == -1) { ++ return -1; ++ } ++ return 0; ++} ++ ++static void check_pending_events(struct backend_seatd *backend) { ++ if (linked_list_empty(&backend->pending_events)) { ++ return; ++ } ++ if (backend->awaiting_pong) { ++ return; ++ } ++ ++ // We have events pending execution, so a dispatch is required. ++ // However, we likely already drained our socket, so there will not be ++ // anything to read. Instead, send a ping request to seatd, so that the ++ // user will be woken up by its response. ++ if (send_ping(backend) == -1) { ++ log_errorf("Could not send ping request: %s", strerror(errno)); ++ return; ++ } ++ backend->awaiting_pong = true; ++} ++ + static int open_device(struct libseat *base, const char *path, int *fd) { + struct backend_seatd *backend = backend_seatd_from_libseat_backend(base); + if (backend->error) { +@@ -481,11 +518,11 @@ static int open_device(struct libseat *base, const char *path, int *fd) { + goto error; + } + +- execute_events(backend); ++ check_pending_events(backend); + return rmsg.device_id; + + error: +- execute_events(backend); ++ check_pending_events(backend); + return -1; + } + +@@ -516,11 +553,11 @@ static int close_device(struct libseat *base, int device_id) { + goto error; + } + +- execute_events(backend); ++ check_pending_events(backend); + return 0; + + error: +- execute_events(backend); ++ check_pending_events(backend); + return -1; + } + +diff --git a/seatd/client.c b/seatd/client.c +index 1bfe94a..220c5d3 100644 +--- a/seatd/client.c ++++ b/seatd/client.c +@@ -309,6 +309,20 @@ error: + return client_send_error(client, errno); + } + ++static int handle_ping(struct client *client) { ++ struct proto_header header = { ++ .opcode = SERVER_PONG, ++ .size = 0, ++ }; ++ ++ if (connection_put(&client->connection, &header, sizeof header) == -1) { ++ log_errorf("Could not write response: %s", strerror(errno)); ++ return -1; ++ } ++ ++ return 0; ++} ++ + static int client_handle_opcode(struct client *client, uint16_t opcode, size_t size) { + int res = 0; + switch (opcode) { +@@ -372,6 +386,14 @@ static int client_handle_opcode(struct client *client, uint16_t opcode, size_t s + res = handle_disable_seat(client); + break; + } ++ case CLIENT_PING: { ++ if (size != 0) { ++ log_error("Protocol error: invalid ping message"); ++ return -1; ++ } ++ res = handle_ping(client); ++ break; ++ } + default: + log_errorf("Protocol error: unknown opcode: %d", opcode); + res = -1; +-- +2.32.0 +
participants (1)
-
crux@crux.nu