wayland: fix resource leaks causing freeze after extended use
Three leaks identified via static analysis: 1. frame_buf_destroy never freed fb->bg_pixmap. Every window with a textured titlebar leaked a full pixman_image_t on close. 2. handle_xwayland_destroy did not clean up frame_bufs (unlike the XDG path). Every XWayland window close leaked 4-5 pixman images (frame + titlebar + resizebar + buttons). 3. wl_deferred_decoration struct leaked if client disconnected before initial_commit fired. Added destroy listener to free it.
This commit is contained in:
parent
c244148e31
commit
1728c38fbe
|
|
@ -28,6 +28,8 @@ extern void *W_GetViewBacking(unsigned long id);
|
|||
void frame_buf_destroy(struct wlr_buffer *wlr_buf)
|
||||
{
|
||||
struct wl_frame_buf *fb = wl_container_of(wlr_buf, fb, base);
|
||||
if (fb->bg_pixmap)
|
||||
pixman_image_unref(fb->bg_pixmap);
|
||||
if (fb->image)
|
||||
pixman_image_unref(fb->image);
|
||||
wfree(fb);
|
||||
|
|
|
|||
|
|
@ -484,9 +484,12 @@ handle_toplevel_destroy(struct wl_listener *listener, void *data)
|
|||
*/
|
||||
struct wl_deferred_decoration {
|
||||
struct wl_listener commit_listener;
|
||||
struct wl_listener destroy_listener;
|
||||
struct wlr_xdg_toplevel_decoration_v1 *deco;
|
||||
};
|
||||
|
||||
static void handle_deferred_decoration_destroy(struct wl_listener *listener, void *data);
|
||||
|
||||
static void
|
||||
handle_deferred_decoration_commit(struct wl_listener *listener, void *data)
|
||||
{
|
||||
|
|
@ -499,11 +502,23 @@ handle_deferred_decoration_commit(struct wl_listener *listener, void *data)
|
|||
return;
|
||||
|
||||
wl_list_remove(&dd->commit_listener.link);
|
||||
wl_list_remove(&dd->destroy_listener.link);
|
||||
wlr_xdg_toplevel_decoration_v1_set_mode(dd->deco,
|
||||
WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
||||
wfree(dd);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_deferred_decoration_destroy(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct wl_deferred_decoration *dd =
|
||||
wl_container_of(listener, dd, destroy_listener);
|
||||
(void)data;
|
||||
wl_list_remove(&dd->commit_listener.link);
|
||||
wl_list_remove(&dd->destroy_listener.link);
|
||||
wfree(dd);
|
||||
}
|
||||
|
||||
void
|
||||
handle_new_toplevel_decoration(struct wl_listener *listener, void *data)
|
||||
{
|
||||
|
|
@ -519,6 +534,8 @@ handle_new_toplevel_decoration(struct wl_listener *listener, void *data)
|
|||
dd->deco = deco;
|
||||
dd->commit_listener.notify = handle_deferred_decoration_commit;
|
||||
wl_signal_add(&surface->surface->events.commit, &dd->commit_listener);
|
||||
dd->destroy_listener.notify = handle_deferred_decoration_destroy;
|
||||
wl_signal_add(&deco->events.destroy, &dd->destroy_listener);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ void view_attach_scene_destroy_listener(struct wl_toplevel_view *view);
|
|||
void wm_dock_app_add(struct wl_toplevel_view *v);
|
||||
void wm_dock_app_remove(WNativeWindow id);
|
||||
void wl_pointer_warp_to(int x, int y);
|
||||
extern void W_UnregisterBacking(unsigned long id);
|
||||
struct wl_frame_buf *frame_buf_find(WNativeWindow id);
|
||||
|
||||
#define VIEW_FROM_LISTENER(ptr, field) \
|
||||
((struct wl_toplevel_view *)((char *)(ptr) - offsetof(struct wl_toplevel_view, field)))
|
||||
|
|
@ -237,7 +239,23 @@ handle_xwayland_destroy(struct wl_listener *listener, void *data)
|
|||
wfree(view->wm_command[ci]);
|
||||
wfree(view->wm_command);
|
||||
}
|
||||
/* Destroy frame_bufs belonging to this window (mirrors handle_toplevel_destroy) */
|
||||
WNativeWindow frame_id = view->frame_id;
|
||||
wfree(view);
|
||||
if (frame_id) {
|
||||
struct wl_frame_buf *_fb, *_next;
|
||||
wl_list_for_each_safe(_fb, _next, &wl_state.frame_list, link) {
|
||||
if (_fb->id == frame_id || _fb->parent_id == frame_id) {
|
||||
if (_fb->scene_buf)
|
||||
wlr_scene_node_destroy(&_fb->scene_buf->node);
|
||||
if (_fb->tree)
|
||||
wlr_scene_node_destroy(&_fb->tree->node);
|
||||
W_UnregisterBacking(_fb->id);
|
||||
wl_list_remove(&_fb->link);
|
||||
wlr_buffer_drop(&_fb->base);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
Loading…
Reference in New Issue