From cc69dc447ee9a9fd2fa6894e583fd66c21e958c4 Mon Sep 17 00:00:00 2001 From: Marius Vlad Date: Mon, 20 Jun 2022 17:51:17 +0300 Subject: [PATCH] clients/window: Defer closing of window Instead of closing the window directly by calling close_handler() use a deferred task to do that instead. That way we avoid a potential invalid access on a link which was previously removed, due to the fact both window_destroy() and touch_handle_up() traverse the same list. This is an alternative to 841. Fixes: #607. Suggested-by: Pekka Paalanen Reported-by: He Yong Signed-off-by: Marius Vlad --- clients/window.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/clients/window.c b/clients/window.c index a0d988f4..60814a21 100644 --- a/clients/window.c +++ b/clients/window.c @@ -240,6 +240,7 @@ struct window { int redraw_needed; int redraw_task_scheduled; struct task redraw_task; + struct task close_task; int resize_needed; int custom; int focused; @@ -1429,13 +1430,23 @@ window_has_focus(struct window *window) return window->focused; } + +static void +close_task_run(struct task *task, uint32_t events) +{ + struct window *window = container_of(task, struct window, close_task); + window->close_handler(window->user_data); +} + static void window_close(struct window *window) { - if (window->close_handler) - window->close_handler(window->user_data); - else + if (window->close_handler && !window->close_task.run) { + window->close_task.run = close_task_run; + display_defer(window->display, &window->close_task); + } else { display_exit(window->display); + } } struct display *