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 <pekka.paalanen@collabora.com>
Reported-by: He Yong <hyyoxhk@163.com>
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
This commit is contained in:
Marius Vlad 2022-06-20 17:51:17 +03:00
parent 57d32722a2
commit cc69dc447e

View file

@ -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 *