aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2023-02-02 11:43:00 +0100
committerSimon Zeni <simon@bl4ckb0ne.ca>2023-02-02 16:45:09 +0000
commitc88ad532ad942c957fe69e7047d6fc5e84dc1a4a (patch)
tree221a5f86cebb2513b1911d52d4956b141f40784e /backend
parent911648f430f250daba2d3467b97cf63102b1355c (diff)
backend/wayland: don't cache next item when destroying buffers
Because wl_buffer.release is per-buffer and not per-commit, the Wayland backend might create multiple struct wlr_wl_buffer per struct wlr_buffer. As a result, the wlr_buffer_unlock() call inside destroy_wl_buffer() can cause another struct wlr_wl_buffer to be destroyed. In backend_destroy() we were iterating the list of buffers with wl_list_for_each_safe(), which is actually not safe in this case: the next buffer is cached, but might be destroyed as a side-effect of calling destroy_wl_buffer(). Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3572
Diffstat (limited to 'backend')
-rw-r--r--backend/wayland/backend.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c
index 9cf4ed5e..720cecc5 100644
--- a/backend/wayland/backend.c
+++ b/backend/wayland/backend.c
@@ -451,8 +451,10 @@ static void backend_destroy(struct wlr_backend *backend) {
wlr_output_destroy(&output->wlr_output);
}
- struct wlr_wl_buffer *buffer, *tmp_buffer;
- wl_list_for_each_safe(buffer, tmp_buffer, &wl->buffers, link) {
+ // Avoid using wl_list_for_each_safe() here: destroying a buffer may
+ // have the side-effect of destroying the next one in the list
+ while (!wl_list_empty(&wl->buffers)) {
+ struct wlr_wl_buffer *buffer = wl_container_of(wl->buffers.next, buffer, link);
destroy_wl_buffer(buffer);
}