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.
This commit is contained in:
Kristian Høgsberg 2011-11-15 22:20:28 -05:00
parent 51f50b8c64
commit 3a1e6df39a
5 changed files with 34 additions and 3 deletions

View file

@ -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">

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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;