From a13c8efdcdf841a6b2f7f7aa2f83f5c8c42bb718 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Sun, 28 Oct 2018 23:28:58 +1300 Subject: [PATCH] Handle sigchld instead of blocking on waitpid This stops any potential blocking when killing swaybg (e.g. reloading config). We also forcefully close their wayland connection, in case they're slow to die and we start a new swaybg. --- include/sway/config.h | 2 -- include/sway/server.h | 2 ++ sway/config/output.c | 26 +++++++++++++++++--------- sway/server.c | 13 +++++++++++++ 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/include/sway/config.h b/include/sway/config.h index 852d55767..263beee8b 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -535,8 +535,6 @@ void load_swaybar(struct bar_config *bar); void load_swaybars(void); -void terminate_swaybg(pid_t pid); - struct bar_config *default_bar_config(void); void free_bar_config(struct bar_config *bar); diff --git a/include/sway/server.h b/include/sway/server.h index 5fced2243..48022797e 100644 --- a/include/sway/server.h +++ b/include/sway/server.h @@ -23,6 +23,8 @@ struct sway_server { struct wl_event_loop *wl_event_loop; const char *socket; + struct wl_event_source *sigchld_source; + struct wlr_backend *backend; struct wlr_compositor *compositor; diff --git a/sway/config/output.c b/sway/config/output.c index 2b0413535..f7216bcd7 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -164,23 +164,31 @@ static void set_mode(struct wlr_output *output, int width, int height, } } -void terminate_swaybg(pid_t pid) { - int ret = kill(pid, SIGTERM); - if (ret != 0) { - wlr_log(WLR_ERROR, "Unable to terminate swaybg [pid: %d]", pid); - } else { - int status; - waitpid(pid, &status, 0); +static void terminate_swaybg(struct wl_display *display, pid_t pid) { + struct wl_client *client; + wl_client_for_each(client, wl_display_get_client_list(display)) { + pid_t p; + wl_client_get_credentials(client, &p, NULL, NULL); + + if (p == pid) { + wl_client_destroy(client); + break; + } + } + + if (kill(pid, SIGTERM) != 0) { + wlr_log_errno(WLR_ERROR, "Unable to terminate swaybg [pid: %d]", (int)pid); } } void apply_output_config(struct output_config *oc, struct sway_output *output) { struct wlr_output *wlr_output = output->wlr_output; + struct wl_display *display = output->server->wl_display; if (oc && oc->enabled == 0) { if (output->enabled) { if (output->bg_pid != 0) { - terminate_swaybg(output->bg_pid); + terminate_swaybg(display, output->bg_pid); output->bg_pid = 0; } output_disable(output); @@ -230,7 +238,7 @@ void apply_output_config(struct output_config *oc, struct sway_output *output) { } if (output->bg_pid != 0) { - terminate_swaybg(output->bg_pid); + terminate_swaybg(display, output->bg_pid); } if (oc && oc->background && config->swaybg_command) { wlr_log(WLR_DEBUG, "Setting background for output %d to %s", diff --git a/sway/server.c b/sway/server.c index f06173d1b..498367828 100644 --- a/sway/server.c +++ b/sway/server.c @@ -1,7 +1,9 @@ #define _POSIX_C_SOURCE 200112L #include +#include #include #include +#include #include #include #include @@ -30,6 +32,14 @@ #include "sway/xwayland.h" #endif +static int sigchld_handler(int signum, void *data) { + while (waitpid(0, NULL, WNOHANG) > 0) { + // Do nothing + } + + return 0; +} + bool server_privileged_prepare(struct sway_server *server) { wlr_log(WLR_DEBUG, "Preparing Wayland server initialization"); server->wl_display = wl_display_create(); @@ -83,6 +93,9 @@ bool server_init(struct sway_server *server) { &server->xdg_shell_surface); server->xdg_shell_surface.notify = handle_xdg_shell_surface; + server->sigchld_source = wl_event_loop_add_signal(server->wl_event_loop, + SIGCHLD, sigchld_handler, NULL); + // TODO: configurable cursor theme and size int cursor_size = 24; const char *cursor_theme = NULL;