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