diff options
author | Marius Vlad <marius.vlad@collabora.com> | 2022-06-20 17:51:17 +0300 |
---|---|---|
committer | Marius Vlad <marius.vlad@collabora.com> | 2022-06-22 15:29:05 +0300 |
commit | cc69dc447ee9a9fd2fa6894e583fd66c21e958c4 (patch) | |
tree | 76fd1c5c88bf1bcf7ec16583525f2514c3126aa2 /clients | |
parent | 57d32722a262edf52ab5f520d9e827bcc647653a (diff) | |
download | weston-cc69dc447ee9a9fd2fa6894e583fd66c21e958c4.tar.gz |
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>
Diffstat (limited to 'clients')
-rw-r--r-- | clients/window.c | 17 |
1 files 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 * |