Add display event to acknowledge ID deletion
authorKristian Høgsberg <krh@bitplanet.net>
Wed, 16 Nov 2011 03:20:28 +0000 (22:20 -0500)
committerKristian Høgsberg <krh@bitplanet.net>
Thu, 17 Nov 2011 22:37:52 +0000 (17:37 -0500)
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.

protocol/wayland.xml
src/connection.c
src/wayland-client.c
src/wayland-server.c
src/wayland-util.h

index 48ba68a..7e6392a 100644 (file)
       <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">
index a10508d..4230f7d 100644 (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;
                        }
index efb7fe6..8f3e106 100644 (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;
        }
index f93aa64..0004c15 100644 (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);
 }
index 608ea03..083bff8 100644 (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;