fix: unlink wayland socket manually instead of calling wl_display_destroy (wlroots 0.19 multi-backend aborts on display destroy during shutdown)

This commit is contained in:
lkn 2026-06-06 11:14:08 +02:00
parent 563b278268
commit bfa715a99e
1 changed files with 15 additions and 11 deletions

View File

@ -879,17 +879,21 @@ wl_display_close(void)
wl_state.cursor = NULL;
}
/* Tear down the Wayland display so the compositor socket is removed.
* Without this, restart (execvp) fails because the new instance finds
* a stale socket at $XDG_RUNTIME_DIR/wayland-N and refuses to start.
*
* The XWayland server was SIGKILL'd above and server->client was
* NULL'd to prevent wlr_xwayland_server_destroy from double-freeing
* the wl_client during display destroy signal dispatch.
*
* All remaining listeners were removed in the WL_LISTENER_REMOVE block
* above, so no dangling signal handlers remain. */
wl_display_destroy(wl_state.display);
/* Clean up the Wayland socket so a new compositor instance can bind.
* wl_display_destroy() would do this, but in wlroots 0.19 it aborts
* because the multi-backend's display-destroy handler iterates freed
* child backend pointers. Since execvp replaces the entire process
* image, all memory and fd resources are reclaimed by the kernel.
* The socket file on disk is the only persistent resource we need
* to remove ourselves. */
if (wl_state.socket_name[0]) {
const char *rt = getenv("XDG_RUNTIME_DIR");
if (rt) {
char path[256];
snprintf(path, sizeof(path), "%s/%s", rt, wl_state.socket_name);
unlink(path);
}
}
unsetenv("WAYLAND_DISPLAY");
wl_state.renderer = NULL;
wl_state.backend = NULL;