diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/connection.c | 7 | ||||
-rw-r--r-- | src/wayland-client.c | 22 | ||||
-rw-r--r-- | src/wayland-server.c | 2 | ||||
-rw-r--r-- | src/wayland-util.h | 2 |
4 files changed, 30 insertions, 3 deletions
diff --git a/src/connection.c b/src/connection.c index a10508d..4230f7d 100644 --- a/src/connection.c +++ b/src/connection.c @@ -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; } diff --git a/src/wayland-client.c b/src/wayland-client.c index efb7fe6..8f3e106 100644 --- a/src/wayland-client.c +++ b/src/wayland-client.c @@ -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; } diff --git a/src/wayland-server.c b/src/wayland-server.c index f93aa64..0004c15 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -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); } diff --git a/src/wayland-util.h b/src/wayland-util.h index 608ea03..083bff8 100644 --- a/src/wayland-util.h +++ b/src/wayland-util.h @@ -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; |