diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2013-07-02 15:39:03 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2013-07-02 17:01:46 -0400 |
commit | c82a52a47e5e01246680b5d257fff7bc42cb48bf (patch) | |
tree | e5245b46e5c282a4df482b2fdca2e3735b593166 | |
parent | b5b11650081f7adb4866fcacd216d3bd83da5024 (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.c | 38 | ||||
-rw-r--r-- | src/wayland-server.h | 2 | ||||
-rw-r--r-- | src/wayland-shm.c | 29 |
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, ®istry_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); |