From da0cd688d6e35ab509341b0ad6cc5ffcb35c04d8 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Thu, 14 Nov 2019 23:55:35 +0100 Subject: [PATCH] launcher-weston-launch: avoid race condition when switching VT merge When using weston-launch launcher deactivating the VT is sometimes racy and leads to Weston still being displayed. The launcher-direct.c backend makes sure that the session signal is emitted first, then DRM master is dropped and finally the VT switch is acknowledged via VT_RELDISP. However, in the weston-launch case the session signal is emitted via a socket message to the weston process, which might get handled a bit later. This leads to dropping DRM master and acknowledging the VT switch prematurely. Add a socket message which allows weston to notify weston-launch that the signal has been emitted and deactivating can be proceeded. Signed-off-by: Stefan Agner Reviewed-by: Emil Velikov --- libweston/launcher-weston-launch.c | 6 ++++- libweston/weston-launch.c | 40 ++++++++++++++++-------------- libweston/weston-launch.h | 3 ++- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/libweston/launcher-weston-launch.c b/libweston/launcher-weston-launch.c index aad8b16e..e3b4e1ac 100644 --- a/libweston/launcher-weston-launch.c +++ b/libweston/launcher-weston-launch.c @@ -201,7 +201,7 @@ static int launcher_weston_launch_data(int fd, uint32_t mask, void *data) { struct launcher_weston_launch *launcher = data; - int len, ret; + int len, ret, reply; if (mask & (WL_EVENT_HANGUP | WL_EVENT_ERROR)) { weston_log("launcher socket closed, exiting\n"); @@ -226,6 +226,10 @@ launcher_weston_launch_data(int fd, uint32_t mask, void *data) launcher->compositor->session_active = false; wl_signal_emit(&launcher->compositor->session_signal, launcher->compositor); + + reply = WESTON_LAUNCHER_DEACTIVATE_DONE; + launcher_weston_launch_send(launcher->fd, &reply, sizeof reply); + break; default: weston_log("unexpected event from weston-launch\n"); diff --git a/libweston/weston-launch.c b/libweston/weston-launch.c index 05525e34..521cb2cb 100644 --- a/libweston/weston-launch.c +++ b/libweston/weston-launch.c @@ -399,6 +399,22 @@ err0: return 0; } +static void +close_input_fds(struct weston_launch *wl) +{ + struct stat s; + int fd; + + for (fd = 3; fd <= wl->last_input_fd; fd++) { + if (fstat(fd, &s) == 0 && major(s.st_rdev) == INPUT_MAJOR) { + /* EVIOCREVOKE may fail if the kernel doesn't + * support it, but all we can do is ignore it. */ + ioctl(fd, EVIOCREVOKE, 0); + close(fd); + } + } +} + static int handle_socket_msg(struct weston_launch *wl) { @@ -430,6 +446,11 @@ handle_socket_msg(struct weston_launch *wl) case WESTON_LAUNCHER_OPEN: ret = handle_open(wl, &msg, len); break; + case WESTON_LAUNCHER_DEACTIVATE_DONE: + close_input_fds(wl); + drmDropMaster(wl->drm_fd); + ioctl(wl->tty, VT_RELDISP, 1); + break; } return ret; @@ -490,22 +511,6 @@ quit(struct weston_launch *wl, int status) exit(status); } -static void -close_input_fds(struct weston_launch *wl) -{ - struct stat s; - int fd; - - for (fd = 3; fd <= wl->last_input_fd; fd++) { - if (fstat(fd, &s) == 0 && major(s.st_rdev) == INPUT_MAJOR) { - /* EVIOCREVOKE may fail if the kernel doesn't - * support it, but all we can do is ignore it. */ - ioctl(fd, EVIOCREVOKE, 0); - close(fd); - } - } -} - static int handle_signal(struct weston_launch *wl) { @@ -551,9 +556,6 @@ handle_signal(struct weston_launch *wl) break; case SIGUSR1: send_reply(wl, WESTON_LAUNCHER_DEACTIVATE); - close_input_fds(wl); - drmDropMaster(wl->drm_fd); - ioctl(wl->tty, VT_RELDISP, 1); break; case SIGUSR2: ioctl(wl->tty, VT_RELDISP, VT_ACKACQ); diff --git a/libweston/weston-launch.h b/libweston/weston-launch.h index bd974de8..575d2cf9 100644 --- a/libweston/weston-launch.h +++ b/libweston/weston-launch.h @@ -33,7 +33,8 @@ enum weston_launcher_opcode { enum weston_launcher_event { WESTON_LAUNCHER_SUCCESS, WESTON_LAUNCHER_ACTIVATE, - WESTON_LAUNCHER_DEACTIVATE + WESTON_LAUNCHER_DEACTIVATE, + WESTON_LAUNCHER_DEACTIVATE_DONE, }; struct weston_launcher_message {