From e8a844355f7d60efb2e0967b1966ee74fd00dc59 Mon Sep 17 00:00:00 2001 From: David Redondo Date: Wed, 31 Jul 2024 07:05:48 +0000 Subject: [PATCH] oeffis: Make ConnectToEIS call async A blocking call can be problematic when done from inside Xwayland to the compositor as the compositor could be doing a blocking X call at the same time. In this instance we found it's likely to happen because this call will happen shortly after the user accepted the This is not a problem for the other calls because the portal API is async for these via request response signalling. --- src/liboeffis.c | 66 ++++++++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/src/liboeffis.c b/src/liboeffis.c index 7d2ec35..52c2d69 100644 --- a/src/liboeffis.c +++ b/src/liboeffis.c @@ -327,43 +327,31 @@ xdp_session_path(char *sender_name, char *token) return xaprintf("/org/freedesktop/portal/desktop/session/%s/%s", sender_name, token); } -static void -portal_connect_to_eis(struct oeffis *oeffis) + +static int +connect_to_eis_returned(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { - _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - _unref_(sd_bus_message) *response = NULL; - sd_bus *bus = oeffis->bus; int eisfd; + struct oeffis *oeffis = userdata; + int rc = sd_bus_message_get_errno(m); - int rc = 0; - with_signals_blocked(SIGALRM) { - rc = sd_bus_call_method(bus, oeffis->busname, - "/org/freedesktop/portal/desktop", - "org.freedesktop.portal.RemoteDesktop", - "ConnectToEIS", - &error, - &response, - "oa{sv}", - oeffis->session_path, - 0); + if (rc > 0) { + oeffis_disconnect(oeffis, "Error calling ConnectToEIS: %s", strerror(rc)); + return rc; } - if (rc < 0) { - oeffis_disconnect(oeffis, "Failed to call ConnectToEIS: %s", strerror(-rc)); - return; - } - - rc = sd_bus_message_read(response, "h", &eisfd); + rc = sd_bus_message_read(m, "h", &eisfd); if (rc < 0) { oeffis_disconnect(oeffis, "Unable to get fd from portal: %s", strerror(-rc)); - return; + return -rc; } /* the fd is owned by the message */ rc = xerrno(xdup(eisfd)); if (rc < 0) { oeffis_disconnect(oeffis, "Failed to dup fd: %s", strerror(-rc)); - return; + return -rc; + } else { eisfd = rc; int flags = fcntl(eisfd, F_GETFL, 0); @@ -373,8 +361,36 @@ portal_connect_to_eis(struct oeffis *oeffis) log_debug("Got fd %d from portal", eisfd); rc = oeffis_set_eis_fd(oeffis, eisfd); - if (rc < 0) + if (rc < 0) { oeffis_disconnect(oeffis, "Failed to set the fd: %s", strerror(-rc)); + return -rc; + } + + return 0; +} + +static void +portal_connect_to_eis(struct oeffis *oeffis) +{ + sd_bus *bus = oeffis->bus; + + int rc = 0; + with_signals_blocked(SIGALRM) { + rc = sd_bus_call_method_async(bus, NULL, oeffis->busname, + "/org/freedesktop/portal/desktop", + "org.freedesktop.portal.RemoteDesktop", + "ConnectToEIS", + &connect_to_eis_returned, + oeffis, + "oa{sv}", + oeffis->session_path, + 0); + } + + if (rc < 0) { + oeffis_disconnect(oeffis, "Failed to call ConnectToEIS: %s", strerror(-rc)); + return; + } } static int