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:
parent
57d32722a2
commit
cc69dc447e
|
@ -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 *
|
||||
|
|
Loading…
Reference in New Issue