[PATCH v2 wayland] shm: Add shm_buffer ref and shm_pool unref functions

Derek Foreman derekf at osg.samsung.com
Mon Oct 5 11:12:12 PDT 2015


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.

Signed-off-by: Derek Foreman <derekf at osg.samsung.com>
---

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         | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 43 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..4f9d9d0 100644
--- a/src/wayland-shm.c
+++ b/src/wayland-shm.c
@@ -412,6 +412,42 @@ 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.
+ *
+ * This refcount keeps the shm pool from being destroyed on client
+ * disconnect, so the compositor must call wl_shm_pool_unref on it
+ * when finished.
+ *
+ * \memberof wl_shm_buffer
+ */
+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.
+ *
+ * \memberof wl_shm_buffer
+ */
+WL_EXPORT void
+wl_shm_pool_unref(struct wl_shm_pool *pool)
+{
+	shm_pool_unref(pool);
+}
+
 static void
 reraise_sigbus(void)
 {
-- 
2.5.3



More information about the wayland-devel mailing list