mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-11-02 09:01:39 -05:00
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:
parent
51f50b8c64
commit
3a1e6df39a
5 changed files with 34 additions and 3 deletions
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue