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>
This commit is contained in:
committed by
Pekka Paalanen
parent
10356a247b
commit
da0cd688d6
@@ -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");
|
||||
|
||||
+21
-19
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user