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 <stefan@agner.ch>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
dev
Stefan Agner 5 years ago committed by Pekka Paalanen
parent 10356a247b
commit da0cd688d6
  1. 6
      libweston/launcher-weston-launch.c
  2. 40
      libweston/weston-launch.c
  3. 3
      libweston/weston-launch.h

@ -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");

@ -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);

@ -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 {

Loading…
Cancel
Save