diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2011-11-15 22:20:28 -0500 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2011-11-17 17:37:52 -0500 |
commit | 3a1e6df39aa34df53c97ce9c7a1bfddf5a97faf3 (patch) | |
tree | 5c103308f52da243bf3cb831ef26736bb760f887 | |
parent | 51f50b8c6425684214e58a0e5ab2515b624feaad (diff) |
Add display event to acknowledge ID deletion
We need to make sure the client doesn't reuse an object ID until the
server has seen the destroy request. When a client destroys an ID
the server will now respond with the display.delete_id event, which lets
the client block reuse until it receives the event.
-rw-r--r-- | protocol/wayland.xml | 4 | ||||
-rw-r--r-- | src/connection.c | 7 | ||||
-rw-r--r-- | src/wayland-client.c | 22 | ||||
-rw-r--r-- | src/wayland-server.c | 2 | ||||
-rw-r--r-- | src/wayland-util.h | 2 |
5 files changed, 34 insertions, 3 deletions
diff --git a/protocol/wayland.xml b/protocol/wayland.xml index 48ba68a..7e6392a 100644 --- a/protocol/wayland.xml +++ b/protocol/wayland.xml @@ -76,6 +76,10 @@ <arg name="name" type="uint" /> </event> + <!-- Server has deleted the id and client can now reuse it. --> + <event name="delete_id"> + <arg name="id" type="uint" /> + </event> </interface> <interface name="wl_callback" version="1"> diff --git a/src/connection.c b/src/connection.c index a10508d..4230f7d 100644 --- a/src/connection.c +++ b/src/connection.c @@ -587,9 +587,14 @@ wl_connection_demarshal(struct wl_connection *connection, closure->args[i] = object; *object = wl_map_lookup(objects, *p); - if (*object == NULL && *p != 0) { + if (*object == WL_ZOMBIE_OBJECT) { + /* references object we've already + * destroyed client side */ + *object = NULL; + } else if (*object == NULL && *p != 0) { printf("unknown object (%d), message %s(%s)\n", *p, message->name, message->signature); + *object = NULL; errno = EINVAL; goto err; } diff --git a/src/wayland-client.c b/src/wayland-client.c index efb7fe6..8f3e106 100644 --- a/src/wayland-client.c +++ b/src/wayland-client.c @@ -141,7 +141,8 @@ wl_proxy_create(struct wl_proxy *factory, const struct wl_interface *interface) WL_EXPORT void wl_proxy_destroy(struct wl_proxy *proxy) { - wl_map_remove(&proxy->display->objects, proxy->object.id); + wl_map_insert_at(&proxy->display->objects, + proxy->object.id, WL_ZOMBIE_OBJECT); free(proxy); } @@ -239,10 +240,23 @@ display_handle_global_remove(void *data, } } +static void +display_handle_delete_id(void *data, struct wl_display *display, uint32_t id) +{ + struct wl_proxy *proxy; + + proxy = wl_map_lookup(&display->objects, id); + if (proxy != WL_ZOMBIE_OBJECT) + fprintf(stderr, "server sent delete_id for live object\n"); + else + wl_map_remove(&display->objects, id); +} + static const struct wl_display_listener display_listener = { display_handle_error, display_handle_global, display_handle_global_remove, + display_handle_delete_id }; static int @@ -412,7 +426,11 @@ handle_event(struct wl_display *display, wl_connection_copy(display->connection, p, size); proxy = wl_map_lookup(&display->objects, id); - if (proxy == NULL || proxy->object.implementation == NULL) { + if (proxy == WL_ZOMBIE_OBJECT) { + fprintf(stderr, "Message to zombie object\n"); + wl_connection_consume(display->connection, size); + return; + } else if (proxy == NULL || proxy->object.implementation == NULL) { wl_connection_consume(display->connection, size); return; } diff --git a/src/wayland-server.c b/src/wayland-server.c index f93aa64..0004c15 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -314,6 +314,8 @@ wl_resource_destroy(struct wl_resource *resource, uint32_t time) { struct wl_client *client = resource->client; + wl_resource_post_event(resource->client->display_resource, + WL_DISPLAY_DELETE_ID, resource->object.id); wl_map_insert_at(&client->objects, resource->object.id, NULL); destroy_resource(resource, &time); } diff --git a/src/wayland-util.h b/src/wayland-util.h index 608ea03..083bff8 100644 --- a/src/wayland-util.h +++ b/src/wayland-util.h @@ -44,6 +44,8 @@ extern "C" { const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) +#define WL_ZOMBIE_OBJECT ((void *) 2) + struct wl_message { const char *name; const char *signature; |