diff options
| author | Sebastian Wick <sebastian.wick@redhat.com> | 2025-03-21 19:43:23 +0100 |
|---|---|---|
| committer | Sebastian Wick <sebastian.wick@redhat.com> | 2025-05-20 21:50:22 +0200 |
| commit | d2a3d33063ea0266eee55a54c8bb1d65a7acaca9 (patch) | |
| tree | 8624288d7c8abf87143d38665be969649218c25b | |
| parent | shm: Add wl_shm_buffer ref and unref functions (diff) | |
| download | wayland-d2a3d33063ea0266eee55a54c8bb1d65a7acaca9.tar wayland-d2a3d33063ea0266eee55a54c8bb1d65a7acaca9.tar.gz wayland-d2a3d33063ea0266eee55a54c8bb1d65a7acaca9.tar.bz2 wayland-d2a3d33063ea0266eee55a54c8bb1d65a7acaca9.tar.lz wayland-d2a3d33063ea0266eee55a54c8bb1d65a7acaca9.tar.xz wayland-d2a3d33063ea0266eee55a54c8bb1d65a7acaca9.tar.zst wayland-d2a3d33063ea0266eee55a54c8bb1d65a7acaca9.zip | |
shm: Generate an error when shm access failed even without a resource
Signed-off-by: Sebastian Wick <sebastian.wick@redhat.com>
| -rw-r--r-- | src/wayland-shm.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/src/wayland-shm.c b/src/wayland-shm.c index bb622b6..b8c7373 100644 --- a/src/wayland-shm.c +++ b/src/wayland-shm.c @@ -86,6 +86,8 @@ struct wl_shm_buffer { struct wl_resource *resource; int internal_refcount; int external_refcount; + struct wl_client *client; + struct wl_listener client_destroy_listener; int32_t width, height; int32_t stride; uint32_t format; @@ -187,6 +189,8 @@ shm_buffer_unref(struct wl_shm_buffer *buffer, bool external) if (buffer->internal_refcount + buffer->external_refcount > 0) return; + if (buffer->client) + wl_list_remove(&buffer->client_destroy_listener.link); shm_pool_unref(buffer->pool, false); free(buffer); } @@ -230,6 +234,17 @@ format_is_supported(struct wl_client *client, uint32_t format) return false; } + +static void +shm_buffer_client_destroy_notify(struct wl_listener *listener, void *data) +{ + struct wl_shm_buffer *buffer = + wl_container_of(listener, buffer, client_destroy_listener); + + buffer->client = NULL; + wl_list_remove(&buffer->client_destroy_listener.link); +} + static void shm_pool_create_buffer(struct wl_client *client, struct wl_resource *resource, uint32_t id, int32_t offset, @@ -262,6 +277,12 @@ shm_pool_create_buffer(struct wl_client *client, struct wl_resource *resource, return; } + buffer->client = client; + buffer->client_destroy_listener.notify = + shm_buffer_client_destroy_notify; + wl_client_add_destroy_listener(buffer->client, + &buffer->client_destroy_listener); + buffer->internal_refcount = 1; buffer->external_refcount = 0; buffer->width = width; @@ -763,6 +784,11 @@ wl_shm_buffer_end_access(struct wl_shm_buffer *buffer) wl_resource_post_error(buffer->resource, WL_SHM_ERROR_INVALID_FD, "error accessing SHM buffer"); + } else if (buffer->client) { + wl_client_post_implementation_error(buffer->client, + "Error accessing SHM buffer of a " + "wl_buffer resource which has " + "already been destroyed"); } sigbus_data->fallback_mapping_used = 0; } |
