From 3e98ffaf9958366b584b360ac12bbc03cd070c07 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 3 Feb 2014 18:36:46 -0500 Subject: [PATCH] wayland-surface: Don't crash if a client destroys a buffer in use This is considered "undefined" by upstream. Right now GTK+ does this a lot, so we shouldn't crash. Let's make them crash instead and send them an error instead. --- src/wayland/meta-wayland-surface.c | 23 +++++++++++++++++++++-- src/wayland/meta-wayland-surface.h | 4 +++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 0dca23e0e..909d62425 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -71,6 +71,17 @@ typedef struct struct wl_listener sibling_destroy_listener; } MetaWaylandSubsurfacePlacementOp; +static void +surface_handle_buffer_destroy (struct wl_listener *listener, void *data) +{ + MetaWaylandSurface *surface = wl_container_of (listener, surface, buffer_destroy_listener); + + wl_resource_post_error (surface->resource, WL_DISPLAY_ERROR_INVALID_OBJECT, + "Destroyed buffer while it was attached to the surface"); + surface->buffer = NULL; + wl_list_remove (&surface->buffer_destroy_listener.link); +} + static void surface_set_buffer (MetaWaylandSurface *surface, MetaWaylandBuffer *buffer) @@ -79,12 +90,18 @@ surface_set_buffer (MetaWaylandSurface *surface, return; if (surface->buffer) - meta_wayland_buffer_unref (surface->buffer); + { + meta_wayland_buffer_unref (surface->buffer); + wl_list_remove (&surface->buffer_destroy_listener.link); + } surface->buffer = buffer; if (surface->buffer) - meta_wayland_buffer_ref (surface->buffer); + { + meta_wayland_buffer_ref (surface->buffer); + wl_signal_add (&surface->buffer->destroy_signal, &surface->buffer_destroy_listener); + } } static void @@ -621,6 +638,8 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, double_buffered_state_init (&surface->pending); + surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy; + surface->surface_actor = g_object_ref_sink (meta_surface_actor_new ()); return surface; } diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 129ce8aea..3e1b29737 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -71,7 +71,6 @@ struct _MetaWaylandSurface { struct wl_resource *resource; MetaWaylandCompositor *compositor; - MetaWaylandBuffer *buffer; MetaSurfaceActor *surface_actor; MetaWindow *window; MetaWaylandSurfaceExtension xdg_surface; @@ -79,6 +78,9 @@ struct _MetaWaylandSurface MetaWaylandSurfaceExtension gtk_surface; MetaWaylandSurfaceExtension subsurface; + MetaWaylandBuffer *buffer; + struct wl_listener buffer_destroy_listener; + GList *subsurfaces; struct {