shm: Add shm_buffer ref and shm_pool unref functions

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 <pekka.paalanen@collabora.co.uk>
Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
This commit is contained in:
Derek Foreman 2015-10-19 20:54:49 -05:00
parent 06fb8bd371
commit eba83cd5e1
2 changed files with 49 additions and 0 deletions

View file

@ -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)
{