From 318d4fdeefa7790cd646d9d984d2c14ab55012c7 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 21 Jan 2012 23:03:09 +0000 Subject: [PATCH] make in-place restarts use socket activation, too (for faster/less flaky tests) --- include/i3.h | 4 +++- src/main.c | 25 ++++++++++++++++---- src/startup.c | 12 +++++++++- testcases/lib/i3test.pm | 3 +++ testcases/t/143-regress-floating-restart.t | 1 - testcases/t/150-regress-dock-restart.t | 3 --- testcases/t/161-regress-borders-restart.t | 2 -- testcases/t/168-regress-fullscreen-restart.t | 1 - testcases/t/185-scratchpad.t | 1 - testcases/t/188-regress-focus-restart.t | 1 - 10 files changed, 37 insertions(+), 16 deletions(-) diff --git a/include/i3.h b/include/i3.h index d6453254..dbe477be 100644 --- a/include/i3.h +++ b/include/i3.h @@ -2,7 +2,7 @@ * vim:ts=4:sw=4:expandtab * * i3 - an improved dynamic tiling window manager - * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE) + * © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE) * * i3.h: global variables that are used all over i3. * @@ -30,6 +30,8 @@ extern struct rlimit original_rlimit_core; /** Whether this version of i3 is a debug build or a release build. */ extern bool debug_build; +/** The number of file descriptors passed via socket activation. */ +extern int listen_fds; extern xcb_connection_t *conn; extern int conn_screen; /** The last timestamp we got from X11 (timestamps are included in some events diff --git a/src/main.c b/src/main.c index 5847204a..7738dacc 100644 --- a/src/main.c +++ b/src/main.c @@ -2,7 +2,7 @@ * vim:ts=4:sw=4:expandtab * * i3 - an improved dynamic tiling window manager - * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE) + * © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE) * * main.c: Initialization, main loop * @@ -28,6 +28,9 @@ struct rlimit original_rlimit_core; /* Whether this version of i3 is a debug build or a release build. */ bool debug_build = false; +/** The number of file descriptors passed via socket activation. */ +int listen_fds; + static int xkb_event_base; int xkb_current_group; @@ -662,14 +665,26 @@ int main(int argc, char *argv[]) { /* Also handle the UNIX domain sockets passed via socket activation. The * parameter 1 means "remove the environment variables", we don’t want to * pass these to child processes. */ - int fds = sd_listen_fds(1); - if (fds < 0) + listen_fds = sd_listen_fds(0); + if (listen_fds < 0) ELOG("socket activation: Error in sd_listen_fds\n"); - else if (fds == 0) + else if (listen_fds == 0) DLOG("socket activation: no sockets passed\n"); else { - for (int fd = SD_LISTEN_FDS_START; fd < (SD_LISTEN_FDS_START + fds); fd++) { + int flags; + for (int fd = SD_LISTEN_FDS_START; + fd < (SD_LISTEN_FDS_START + listen_fds); + fd++) { DLOG("socket activation: also listening on fd %d\n", fd); + + /* sd_listen_fds() enables FD_CLOEXEC by default. + * However, we need to keep the file descriptors open for in-place + * restarting, therefore we explicitly disable FD_CLOEXEC. */ + if ((flags = fcntl(fd, F_GETFD)) < 0 || + fcntl(fd, F_SETFD, flags & ~FD_CLOEXEC) < 0) { + ELOG("Could not disable FD_CLOEXEC on fd %d\n", fd); + } + struct ev_io *ipc_io = scalloc(sizeof(struct ev_io)); ev_io_init(ipc_io, ipc_new_client, fd, EV_READ); ev_io_start(main_loop, ipc_io); diff --git a/src/startup.c b/src/startup.c index 86e66eaa..bcc2415a 100644 --- a/src/startup.c +++ b/src/startup.c @@ -2,7 +2,7 @@ * vim:ts=4:sw=4:expandtab * * i3 - an improved dynamic tiling window manager - * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE) + * © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE) * * startup.c: Startup notification code. Ensures a startup notification context * is setup when launching applications. We store the current @@ -11,6 +11,7 @@ * */ #include "all.h" +#include "sd-daemon.h" #include #include @@ -113,6 +114,15 @@ void start_application(const char *command, bool no_startup_id) { /* Child process */ setsid(); setrlimit(RLIMIT_CORE, &original_rlimit_core); + /* Close all socket activation file descriptors explicitly, we disabled + * FD_CLOEXEC to keep them open when restarting i3. */ + for (int fd = SD_LISTEN_FDS_START; + fd < (SD_LISTEN_FDS_START + listen_fds); + fd++) { + close(fd); + } + unsetenv("LISTEN_PID"); + unsetenv("LISTEN_FDS"); if (fork() == 0) { /* Setup the environment variable(s) */ if (!no_startup_id) diff --git a/testcases/lib/i3test.pm b/testcases/lib/i3test.pm index 1e70bf52..09c66dc5 100644 --- a/testcases/lib/i3test.pm +++ b/testcases/lib/i3test.pm @@ -498,6 +498,9 @@ sub get_socket_path { my $cookie = $x->get_property(0, $x->get_root_window(), $atom->id, GET_PROPERTY_TYPE_ANY, 0, 256); my $reply = $x->get_property_reply($cookie->{sequence}); my $socketpath = $reply->{value}; + if ($socketpath eq "/tmp/nested-$ENV{DISPLAY}") { + $socketpath .= '-activation'; + } $_cached_socket_path = $socketpath; return $socketpath; } diff --git a/testcases/t/143-regress-floating-restart.t b/testcases/t/143-regress-floating-restart.t index 666c6624..03d9ec12 100644 --- a/testcases/t/143-regress-floating-restart.t +++ b/testcases/t/143-regress-floating-restart.t @@ -15,7 +15,6 @@ is(scalar @{$ws->{nodes}}, 0, 'no tiling nodes'); is(scalar @{$ws->{floating_nodes}}, 1, 'precisely one floating node'); cmd 'restart'; -sleep 0.5; diag('Checking if i3 still lives'); diff --git a/testcases/t/150-regress-dock-restart.t b/testcases/t/150-regress-dock-restart.t index 7e5a5520..3cda6059 100644 --- a/testcases/t/150-regress-dock-restart.t +++ b/testcases/t/150-regress-dock-restart.t @@ -38,8 +38,6 @@ is($docknode->{rect}->{height}, 30, 'dock node has unchanged height'); # perform an inplace-restart cmd 'restart'; -sleep 0.25; - does_i3_live; @@ -78,7 +76,6 @@ $docknode = $docked[0]; is($docknode->{rect}->{height}, 20, 'dock node has unchanged height'); cmd 'restart'; -sleep 0.25; @docked = get_dock_clients; is(@docked, 1, 'one dock client found'); diff --git a/testcases/t/161-regress-borders-restart.t b/testcases/t/161-regress-borders-restart.t index 6e1f64f0..9ae677e7 100644 --- a/testcases/t/161-regress-borders-restart.t +++ b/testcases/t/161-regress-borders-restart.t @@ -28,8 +28,6 @@ is(get_border_style(), '1pixel', 'border style 1pixel after changing'); # perform an inplace-restart cmd 'restart'; -sleep 0.25; - does_i3_live; is(get_border_style(), '1pixel', 'border style still 1pixel after restart'); diff --git a/testcases/t/168-regress-fullscreen-restart.t b/testcases/t/168-regress-fullscreen-restart.t index 27812565..ec6d4821 100644 --- a/testcases/t/168-regress-fullscreen-restart.t +++ b/testcases/t/168-regress-fullscreen-restart.t @@ -17,7 +17,6 @@ cmd 'fullscreen'; sync_with_i3; cmd 'restart'; -sleep 1; does_i3_live; diff --git a/testcases/t/185-scratchpad.t b/testcases/t/185-scratchpad.t index 54759034..06debab3 100644 --- a/testcases/t/185-scratchpad.t +++ b/testcases/t/185-scratchpad.t @@ -278,7 +278,6 @@ my $old_nodes = scalar @{$__i3_scratch->{nodes}}; my $old_floating_nodes = scalar @{$__i3_scratch->{floating_nodes}}; cmd 'restart'; -sleep 1; does_i3_live; diff --git a/testcases/t/188-regress-focus-restart.t b/testcases/t/188-regress-focus-restart.t index ba3bb072..1de9f366 100644 --- a/testcases/t/188-regress-focus-restart.t +++ b/testcases/t/188-regress-focus-restart.t @@ -20,7 +20,6 @@ is($focus->[0], $nodes->[0]->{id}, 'first node focused'); is($focus->[1], $nodes->[1]->{id}, 'second node second in focus stack'); cmd 'restart'; -sleep 1; does_i3_live; -- 2.39.5