[PATCH] xwayland: Destroy wl_buffers only after they are released

Rui Matos tiagomatos at gmail.com
Tue Feb 11 07:34:13 PST 2014


Destroying a wl_buffer that is still attached to a wl_surface is
undefined behavior according to the wayland protocol. We should delay
the destruction until we get the release event.
---

So, I'm not sure why there was this comment saying that it was safe to
do this, perhaps it was in an old protocol version?

In any case, this has been making xwayland crash under mutter ever
since this mutter commit
https://git.gnome.org/browse/mutter/commit/?h=wayland&id=3e98ffaf9958366b584b360ac12bbc03cd070c07 .

 hw/xfree86/xwayland/xwayland-window.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/hw/xfree86/xwayland/xwayland-window.c b/hw/xfree86/xwayland/xwayland-window.c
index a2a8206..a005cc6 100644
--- a/hw/xfree86/xwayland/xwayland-window.c
+++ b/hw/xfree86/xwayland/xwayland-window.c
@@ -43,6 +43,16 @@
 static DevPrivateKeyRec xwl_window_private_key;
 
 static void
+free_buffer(void *data, struct wl_buffer *buffer)
+{
+    wl_buffer_destroy(buffer);
+}
+
+static const struct wl_buffer_listener buffer_listener = {
+    free_buffer,
+};
+
+static void
 free_pixmap(void *data, struct wl_callback *callback, uint32_t time)
 {
     PixmapPtr pixmap = data;
@@ -62,10 +72,8 @@ xwl_window_attach(struct xwl_window *xwl_window, PixmapPtr pixmap)
     struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
     struct wl_callback *callback;
 
-    /* We can safely destroy the buffer because we only use one buffer
-     * per surface in xwayland model */
     if (xwl_window->buffer)
-        wl_buffer_destroy(xwl_window->buffer);
+        wl_buffer_add_listener(xwl_window->buffer, &buffer_listener, NULL);
 
     xwl_screen->driver->create_window_buffer(xwl_window, pixmap);
 
@@ -185,7 +193,7 @@ xwl_unrealize_window(WindowPtr window)
 	return ret;
 
     if (xwl_window->buffer)
-	wl_buffer_destroy(xwl_window->buffer);
+        wl_buffer_add_listener(xwl_window->buffer, &buffer_listener, NULL);
     wl_surface_destroy(xwl_window->surface);
     xorg_list_del(&xwl_window->link);
     if (RegionNotEmpty(DamageRegion(xwl_window->damage)))
-- 
1.8.3.1



More information about the wayland-devel mailing list