Sometimes the compositor wants to make sure a shm pool doesn't disappear out from under it.
For example, in Enlightenment, rendering happens in a separate thread while the main thread can still dispatch events. If a client is destroyed during rendering, all its resources are cleaned up and its shm pools are unmapped. This causes the rendering thread to segfault. This patch adds a way for the compositor to increment the refcount of the shm pool so it can't disappear, and decrement it when it's finished. The ref/unref are asymmetrical (ref returns the pool) because it's possible the buffer itself will be gone when you need to unref the pool. Reviewed-by: Pekka Paalanen <[email protected]> Signed-off-by: Derek Foreman <[email protected]> --- Changes from v2: Slightly improved doxygen Changes from v1: renamed functions to wl_shm_buffer_ref_pool and wl_shm_pool_unref added doxy src/wayland-server-core.h | 7 +++++++ src/wayland-shm.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) src/wayland-server-core.h | 7 +++++++ src/wayland-shm.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h index e605432..4c2bdfe 100644 --- a/src/wayland-server-core.h +++ b/src/wayland-server-core.h @@ -362,6 +362,7 @@ wl_resource_get_destroy_listener(struct wl_resource *resource, resource = tmp, \ tmp = wl_resource_from_link(wl_resource_get_link(resource)->next)) +struct wl_shm_pool; struct wl_shm_buffer; void @@ -388,6 +389,12 @@ wl_shm_buffer_get_width(struct wl_shm_buffer *buffer); int32_t wl_shm_buffer_get_height(struct wl_shm_buffer *buffer); +struct wl_shm_pool * +wl_shm_buffer_ref_pool(struct wl_shm_buffer *buffer); + +void +wl_shm_pool_unref(struct wl_shm_pool *pool); + int wl_display_init_shm(struct wl_display *display); diff --git a/src/wayland-shm.c b/src/wayland-shm.c index 5c419fa..1ab8f89 100644 --- a/src/wayland-shm.c +++ b/src/wayland-shm.c @@ -412,6 +412,48 @@ wl_shm_buffer_get_height(struct wl_shm_buffer *buffer) return buffer->height; } +/** Get a reference to a shm_buffer's shm_pool + * + * \param buffer The buffer object + * + * Returns a pointer to a buffer's shm_pool and increases the + * shm_pool refcount. + * + * The compositor must remember to call wl_shm_pool_unref when + * it no longer needs the reference to ensure proper destruction + * of the pool. + * + * \memberof wl_shm_buffer + * \sa wl_shm_pool_unref + */ +WL_EXPORT struct wl_shm_pool * +wl_shm_buffer_ref_pool(struct wl_shm_buffer *buffer) +{ + assert(buffer->pool->refcount); + + buffer->pool->refcount++; + return buffer->pool; +} + +/** Unreference a shm_pool + * + * \param buffer The pool object + * + * Drops a reference to a wl_shm_pool object. + * + * This is only necessary if the compositor has explicitly + * taken a reference with wl_shm_buffer_ref_pool(), otherwise + * the pool will be automatically destroyed when appropriate. + * + * \memberof wl_shm_pool + * \sa wl_shm_buffer_ref_pool + */ +WL_EXPORT void +wl_shm_pool_unref(struct wl_shm_pool *pool) +{ + shm_pool_unref(pool); +} + static void reraise_sigbus(void) { -- 2.6.1 _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
