<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">
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;
}
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);
}
}
}
+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
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;
}
{
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);
}