summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2011-11-15 22:20:28 -0500
committerKristian Høgsberg <krh@bitplanet.net>2011-11-17 17:37:52 -0500
commit3a1e6df39aa34df53c97ce9c7a1bfddf5a97faf3 (patch)
tree5c103308f52da243bf3cb831ef26736bb760f887 /src
parent51f50b8c6425684214e58a0e5ab2515b624feaad (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.
Diffstat (limited to 'src')
-rw-r--r--src/connection.c7
-rw-r--r--src/wayland-client.c22
-rw-r--r--src/wayland-server.c2
-rw-r--r--src/wayland-util.h2
4 files changed, 30 insertions, 3 deletions
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;