mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-11-03 09:01:42 -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" />
|
<arg name="name" type="uint" />
|
||||||
</event>
|
</event>
|
||||||
|
|
||||||
|
<!-- Server has deleted the id and client can now reuse it. -->
|
||||||
|
<event name="delete_id">
|
||||||
|
<arg name="id" type="uint" />
|
||||||
|
</event>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="wl_callback" version="1">
|
<interface name="wl_callback" version="1">
|
||||||
|
|
|
||||||
|
|
@ -587,9 +587,14 @@ wl_connection_demarshal(struct wl_connection *connection,
|
||||||
closure->args[i] = object;
|
closure->args[i] = object;
|
||||||
|
|
||||||
*object = wl_map_lookup(objects, *p);
|
*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",
|
printf("unknown object (%d), message %s(%s)\n",
|
||||||
*p, message->name, message->signature);
|
*p, message->name, message->signature);
|
||||||
|
*object = NULL;
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,8 @@ wl_proxy_create(struct wl_proxy *factory, const struct wl_interface *interface)
|
||||||
WL_EXPORT void
|
WL_EXPORT void
|
||||||
wl_proxy_destroy(struct wl_proxy *proxy)
|
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);
|
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 = {
|
static const struct wl_display_listener display_listener = {
|
||||||
display_handle_error,
|
display_handle_error,
|
||||||
display_handle_global,
|
display_handle_global,
|
||||||
display_handle_global_remove,
|
display_handle_global_remove,
|
||||||
|
display_handle_delete_id
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -412,7 +426,11 @@ handle_event(struct wl_display *display,
|
||||||
wl_connection_copy(display->connection, p, size);
|
wl_connection_copy(display->connection, p, size);
|
||||||
proxy = wl_map_lookup(&display->objects, id);
|
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);
|
wl_connection_consume(display->connection, size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -314,6 +314,8 @@ wl_resource_destroy(struct wl_resource *resource, uint32_t time)
|
||||||
{
|
{
|
||||||
struct wl_client *client = resource->client;
|
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);
|
wl_map_insert_at(&client->objects, resource->object.id, NULL);
|
||||||
destroy_resource(resource, &time);
|
destroy_resource(resource, &time);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,8 @@ extern "C" {
|
||||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
(type *)( (char *)__mptr - offsetof(type,member) );})
|
||||||
|
|
||||||
|
#define WL_ZOMBIE_OBJECT ((void *) 2)
|
||||||
|
|
||||||
struct wl_message {
|
struct wl_message {
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *signature;
|
const char *signature;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue