summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2013-07-02 15:39:03 -0400
committerKristian Høgsberg <krh@bitplanet.net>2013-07-02 17:01:46 -0400
commitc82a52a47e5e01246680b5d257fff7bc42cb48bf (patch)
treee5245b46e5c282a4df482b2fdca2e3735b593166
parentb5b11650081f7adb4866fcacd216d3bd83da5024 (diff)
wayland-server: Remove error event posting from wl_resource_create
The wl_client_add/new_object() functions sends out an NO_MEMORY error if the allocation fails. This was convenient in a couple of places where that was all the error handling that was needed. Unfortunately that looks like out-of-memory isn't handled at the call site and set a bad precedent for not cleaning up properly or not handling at all. As we're introducing wl_resource_create() as a replacement for those two functions, let's remove the automatic error event posting and require the caller to do that if necessary. This commit also introduces a new helper, wl_client_post_no_memory() to make it possible to send NO_MEMORY events from bind where we don't have a wl_resource.
-rw-r--r--src/wayland-server.c38
-rw-r--r--src/wayland-server.h2
-rw-r--r--src/wayland-shm.c29
3 files changed, 60 insertions, 9 deletions
diff --git a/src/wayland-server.c b/src/wayland-server.c
index 33fdb20..4efc270 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -405,6 +405,13 @@ wl_client_get_object(struct wl_client *client, uint32_t id)
}
WL_EXPORT void
+wl_client_post_no_memory(struct wl_client *client)
+{
+ wl_resource_post_error(client->display_resource,
+ WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
+}
+
+WL_EXPORT void
wl_resource_post_no_memory(struct wl_resource *resource)
{
wl_resource_post_error(resource->client->display_resource,
@@ -599,6 +606,11 @@ display_sync(struct wl_client *client,
uint32_t serial;
callback = wl_resource_create(client, &wl_callback_interface, 1, id);
+ if (callback == NULL) {
+ wl_client_post_no_memory(client);
+ return;
+ }
+
serial = wl_display_get_serial(client->display);
wl_callback_send_done(callback, serial);
wl_resource_destroy(callback);
@@ -621,6 +633,11 @@ display_get_registry(struct wl_client *client,
registry_resource =
wl_resource_create(client, &wl_registry_interface, 1, id);
+ if (registry_resource == NULL) {
+ wl_client_post_no_memory(client);
+ return;
+ }
+
wl_resource_set_implementation(registry_resource,
&registry_interface,
display, unbind_resource);
@@ -655,6 +672,11 @@ bind_display(struct wl_client *client,
client->display_resource =
wl_resource_create(client, &wl_display_interface, 1, id);
+ if (client->display_resource == NULL) {
+ wl_client_post_no_memory(client);
+ return;
+ }
+
wl_resource_set_implementation(client->display_resource,
&display_interface, display,
destroy_client_display_resource);
@@ -1007,10 +1029,8 @@ wl_resource_create(struct wl_client *client,
struct wl_resource *resource;
resource = malloc(sizeof *resource);
- if (resource == NULL) {
- wl_resource_post_no_memory(client->display_resource);
+ if (resource == NULL)
return NULL;
- }
if (id == 0)
id = wl_map_insert_new(&client->objects, 0, NULL);
@@ -1087,7 +1107,11 @@ wl_client_add_object(struct wl_client *client,
struct wl_resource *resource;
resource = wl_resource_create(client, interface, -1, id);
- wl_resource_set_implementation(resource, implementation, data, NULL);
+ if (resource == NULL)
+ wl_client_post_no_memory(client);
+ else
+ wl_resource_set_implementation(resource,
+ implementation, data, NULL);
return resource;
}
@@ -1105,7 +1129,11 @@ wl_client_new_object(struct wl_client *client,
struct wl_resource *resource;
resource = wl_resource_create(client, interface, -1, 0);
- wl_resource_set_implementation(resource, implementation, data, NULL);
+ if (resource == NULL)
+ wl_client_post_no_memory(client);
+ else
+ wl_resource_set_implementation(resource,
+ implementation, data, NULL);
return resource;
}
diff --git a/src/wayland-server.h b/src/wayland-server.h
index 4378983..0a798f4 100644
--- a/src/wayland-server.h
+++ b/src/wayland-server.h
@@ -128,6 +128,8 @@ struct wl_listener *wl_client_get_destroy_listener(struct wl_client *client,
struct wl_resource *
wl_client_get_object(struct wl_client *client, uint32_t id);
+void
+wl_client_post_no_memory(struct wl_client *client);
struct wl_listener {
struct wl_list link;
diff --git a/src/wayland-shm.c b/src/wayland-shm.c
index dc9731b..0d3c95c 100644
--- a/src/wayland-shm.c
+++ b/src/wayland-shm.c
@@ -115,7 +115,7 @@ shm_pool_create_buffer(struct wl_client *client, struct wl_resource *resource,
buffer = malloc(sizeof *buffer);
if (buffer == NULL) {
- wl_resource_post_no_memory(resource);
+ wl_client_post_no_memory(client);
return;
}
@@ -129,6 +129,13 @@ shm_pool_create_buffer(struct wl_client *client, struct wl_resource *resource,
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);
+ free(buffer);
+ return;
+ }
+
wl_resource_set_implementation(buffer->resource,
&shm_buffer_interface,
buffer, destroy_buffer);
@@ -182,7 +189,7 @@ shm_create_pool(struct wl_client *client, struct wl_resource *resource,
pool = malloc(sizeof *pool);
if (pool == NULL) {
- wl_resource_post_no_memory(resource);
+ wl_client_post_no_memory(client);
goto err_close;
}
@@ -207,8 +214,12 @@ shm_create_pool(struct wl_client *client, struct wl_resource *resource,
pool->resource =
wl_resource_create(client, &wl_shm_pool_interface, 1, id);
- if (!pool->resource)
- goto err_free;
+ if (!pool->resource) {
+ wl_client_post_no_memory(client);
+ munmap(pool->data, pool->size);
+ free(pool);
+ return;
+ }
wl_resource_set_implementation(pool->resource,
&shm_pool_interface,
@@ -233,6 +244,11 @@ bind_shm(struct wl_client *client,
struct wl_resource *resource;
resource = wl_resource_create(client, &wl_shm_interface, 1, id);
+ if (!resource) {
+ wl_client_post_no_memory(client);
+ return;
+ }
+
wl_resource_set_implementation(resource, &shm_interface, data, NULL);
wl_shm_send_format(resource, WL_SHM_FORMAT_ARGB8888);
@@ -276,6 +292,11 @@ wl_shm_buffer_create(struct wl_client *client,
buffer->resource =
wl_resource_create(client, &wl_buffer_interface, 1, id);
+ if (buffer->resource == NULL) {
+ free(buffer);
+ return NULL;
+ }
+
wl_resource_set_implementation(buffer->resource,
&shm_buffer_interface,
buffer, destroy_buffer);