Commit 3a1e6df3 authored by Kristian Høgsberg's avatar Kristian Høgsberg
Browse files

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.
parent 51f50b8c
......@@ -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">
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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);
}
......
......@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment