summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Foreman <derekf@osg.samsung.com>2016-02-09 16:03:47 -0600
committerBryce Harrington <bryce@osg.samsung.com>2016-03-08 16:54:25 -0800
commit442f4435868c1ea37e99d3f4fb316434e96faab1 (patch)
tree8cbf16fe6b86de201d538ade3cd9c2180e02e4e4
parent5fe7e7ca78eb8c5435f35ed47b54aabdbdcaadf7 (diff)
downloadwayland-442f4435868c1ea37e99d3f4fb316434e96faab1.tar.gz
shm: Split pool reference counting into external and internal references
This is a preliminary step towards deferring shm resize operations until after the compositor has released all external references on a pool. Signed-off-by: Derek Foreman <derekf@osg.samsung.com> Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
-rw-r--r--src/wayland-shm.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/src/wayland-shm.c b/src/wayland-shm.c
index 81bf657..79c58df 100644
--- a/src/wayland-shm.c
+++ b/src/wayland-shm.c
@@ -52,7 +52,8 @@ static struct sigaction wl_shm_old_sigbus_action;
struct wl_shm_pool {
struct wl_resource *resource;
- int refcount;
+ int internal_refcount;
+ int external_refcount;
char *data;
int32_t size;
};
@@ -73,10 +74,14 @@ struct wl_shm_sigbus_data {
};
static void
-shm_pool_unref(struct wl_shm_pool *pool)
+shm_pool_unref(struct wl_shm_pool *pool, bool external)
{
- pool->refcount--;
- if (pool->refcount)
+ if (external)
+ pool->external_refcount--;
+ else
+ pool->internal_refcount--;
+
+ if (pool->internal_refcount + pool->external_refcount)
return;
munmap(pool->data, pool->size);
@@ -89,7 +94,7 @@ destroy_buffer(struct wl_resource *resource)
struct wl_shm_buffer *buffer = wl_resource_get_user_data(resource);
if (buffer->pool)
- shm_pool_unref(buffer->pool);
+ shm_pool_unref(buffer->pool, false);
free(buffer);
}
@@ -162,13 +167,13 @@ shm_pool_create_buffer(struct wl_client *client, struct wl_resource *resource,
buffer->stride = stride;
buffer->offset = offset;
buffer->pool = pool;
- pool->refcount++;
+ pool->internal_refcount++;
buffer->resource =
wl_resource_create(client, &wl_buffer_interface, 1, id);
if (buffer->resource == NULL) {
wl_client_post_no_memory(client);
- shm_pool_unref(pool);
+ shm_pool_unref(pool, false);
free(buffer);
return;
}
@@ -183,7 +188,7 @@ destroy_pool(struct wl_resource *resource)
{
struct wl_shm_pool *pool = wl_resource_get_user_data(resource);
- shm_pool_unref(pool);
+ shm_pool_unref(pool, false);
}
static void
@@ -243,7 +248,8 @@ shm_create_pool(struct wl_client *client, struct wl_resource *resource,
goto err_close;
}
- pool->refcount = 1;
+ pool->internal_refcount = 1;
+ pool->external_refcount = 0;
pool->size = size;
pool->data = mmap(NULL, size,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
@@ -396,9 +402,10 @@ wl_shm_buffer_get_height(struct wl_shm_buffer *buffer)
WL_EXPORT struct wl_shm_pool *
wl_shm_buffer_ref_pool(struct wl_shm_buffer *buffer)
{
- assert(buffer->pool->refcount);
+ assert(buffer->pool->internal_refcount +
+ buffer->pool->external_refcount);
- buffer->pool->refcount++;
+ buffer->pool->external_refcount++;
return buffer->pool;
}
@@ -418,7 +425,7 @@ wl_shm_buffer_ref_pool(struct wl_shm_buffer *buffer)
WL_EXPORT void
wl_shm_pool_unref(struct wl_shm_pool *pool)
{
- shm_pool_unref(pool);
+ shm_pool_unref(pool, true);
}
static void