[PATCH wayland 2/4] Add support for flags in the wl_map API and add a WL_MAP_ENTRY_LEGACY flag

Kristian Høgsberg hoegsberg at gmail.com
Tue Jun 4 21:55:48 PDT 2013


On Sat, Jun 01, 2013 at 05:40:53PM -0500, Jason Ekstrand wrote:
> The implementation in this commit allows for one bit worth of flags.  If
> more flags are desired at a future date, then the wl_map implementation
> will have to change but the wl_map API will not.

Looks better with the accessor macros - committed.

Kristian

> Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
> ---
>  src/wayland-client.c  | 12 ++++++------
>  src/wayland-private.h | 13 +++++++++++--
>  src/wayland-server.c  | 12 ++++++------
>  src/wayland-util.c    | 41 +++++++++++++++++++++++++++++++++++------
>  4 files changed, 58 insertions(+), 20 deletions(-)
> 
> diff --git a/src/wayland-client.c b/src/wayland-client.c
> index 0f5e093..bea73e0 100644
> --- a/src/wayland-client.c
> +++ b/src/wayland-client.c
> @@ -226,7 +226,7 @@ wl_proxy_create(struct wl_proxy *factory, const struct wl_interface *interface)
>  	proxy->refcount = 1;
>  
>  	pthread_mutex_lock(&display->mutex);
> -	proxy->object.id = wl_map_insert_new(&display->objects, proxy);
> +	proxy->object.id = wl_map_insert_new(&display->objects, 0, proxy);
>  	pthread_mutex_unlock(&display->mutex);
>  
>  	return proxy;
> @@ -252,7 +252,7 @@ wl_proxy_create_for_id(struct wl_proxy *factory,
>  	proxy->flags = 0;
>  	proxy->refcount = 1;
>  
> -	wl_map_insert_at(&display->objects, id, proxy);
> +	wl_map_insert_at(&display->objects, 0, id, proxy);
>  
>  	return proxy;
>  }
> @@ -273,10 +273,10 @@ wl_proxy_destroy(struct wl_proxy *proxy)
>  	if (proxy->flags & WL_PROXY_FLAG_ID_DELETED)
>  		wl_map_remove(&proxy->display->objects, proxy->object.id);
>  	else if (proxy->object.id < WL_SERVER_ID_START)
> -		wl_map_insert_at(&proxy->display->objects,
> +		wl_map_insert_at(&proxy->display->objects, 0,
>  				 proxy->object.id, WL_ZOMBIE_OBJECT);
>  	else
> -		wl_map_insert_at(&proxy->display->objects,
> +		wl_map_insert_at(&proxy->display->objects, 0,
>  				 proxy->object.id, NULL);
>  
>  
> @@ -522,11 +522,11 @@ wl_display_connect_to_fd(int fd)
>  	wl_list_init(&display->event_queue_list);
>  	pthread_mutex_init(&display->mutex, NULL);
>  
> -	wl_map_insert_new(&display->objects, NULL);
> +	wl_map_insert_new(&display->objects, 0, NULL);
>  
>  	display->proxy.object.interface = &wl_display_interface;
>  	display->proxy.object.id =
> -		wl_map_insert_new(&display->objects, display);
> +		wl_map_insert_new(&display->objects, 0, display);
>  	display->proxy.display = display;
>  	display->proxy.object.implementation = (void(**)(void)) &display_listener;
>  	display->proxy.user_data = display;
> diff --git a/src/wayland-private.h b/src/wayland-private.h
> index 270b470..a648538 100644
> --- a/src/wayland-private.h
> +++ b/src/wayland-private.h
> @@ -41,6 +41,14 @@
>  #define WL_SERVER_ID_START 0xff000000
>  #define WL_CLOSURE_MAX_ARGS 20
>  
> +/* Flags for wl_map_insert_new and wl_map_insert_at.  Flags can be queried with
> + * wl_map_lookup_flags.  The current implementation has room for 1 bit worth of
> + * flags.  If more flags are ever added, the implementation of wl_map will have
> + * to change to allow for new flags */
> +enum wl_map_entry_flags {
> +	WL_MAP_ENTRY_LEGACY = (1 << 0)
> +};
> +
>  struct wl_map {
>  	struct wl_array client_entries;
>  	struct wl_array server_entries;
> @@ -52,11 +60,12 @@ typedef void (*wl_iterator_func_t)(void *element, void *data);
>  
>  void wl_map_init(struct wl_map *map, uint32_t side);
>  void wl_map_release(struct wl_map *map);
> -uint32_t wl_map_insert_new(struct wl_map *map, void *data);
> -int wl_map_insert_at(struct wl_map *map, uint32_t i, void *data);
> +uint32_t wl_map_insert_new(struct wl_map *map, uint32_t flags, void *data);
> +int wl_map_insert_at(struct wl_map *map, uint32_t flags, uint32_t i, void *data);
>  int wl_map_reserve_new(struct wl_map *map, uint32_t i);
>  void wl_map_remove(struct wl_map *map, uint32_t i);
>  void *wl_map_lookup(struct wl_map *map, uint32_t i);
> +uint32_t wl_map_lookup_flags(struct wl_map *map, uint32_t i);
>  void wl_map_for_each(struct wl_map *map, wl_iterator_func_t func, void *data);
>  
>  struct wl_connection;
> diff --git a/src/wayland-server.c b/src/wayland-server.c
> index c96be56..2d13d9d 100644
> --- a/src/wayland-server.c
> +++ b/src/wayland-server.c
> @@ -338,7 +338,7 @@ wl_client_create(struct wl_display *display, int fd)
>  
>  	wl_map_init(&client->objects, WL_MAP_SERVER_SIDE);
>  
> -	if (wl_map_insert_at(&client->objects, 0, NULL) < 0)
> +	if (wl_map_insert_at(&client->objects, 0, 0, NULL) < 0)
>  		goto err_map;
>  
>  	wl_signal_init(&client->destroy_signal);
> @@ -379,8 +379,8 @@ wl_client_add_resource(struct wl_client *client,
>  {
>  	if (resource->object.id == 0) {
>  		resource->object.id =
> -			wl_map_insert_new(&client->objects, resource);
> -	} else if (wl_map_insert_at(&client->objects,
> +			wl_map_insert_new(&client->objects, 0, resource);
> +	} else if (wl_map_insert_at(&client->objects, 0,
>  				  resource->object.id, resource) < 0) {
>  		wl_resource_post_error(client->display_resource,
>  				       WL_DISPLAY_ERROR_INVALID_OBJECT,
> @@ -433,7 +433,7 @@ wl_resource_destroy(struct wl_resource *resource)
>  			wl_resource_queue_event(client->display_resource,
>  						WL_DISPLAY_DELETE_ID, id);
>  		}
> -		wl_map_insert_at(&client->objects, id, NULL);
> +		wl_map_insert_at(&client->objects, 0, id, NULL);
>  	} else {
>  		wl_map_remove(&client->objects, id);
>  	}
> @@ -912,7 +912,7 @@ wl_client_add_object(struct wl_client *client,
>  	resource->client = client;
>  	resource->destroy = (void *) free;
>  
> -	if (wl_map_insert_at(&client->objects, resource->object.id, resource) < 0) {
> +	if (wl_map_insert_at(&client->objects, 0, resource->object.id, resource) < 0) {
>  		wl_resource_post_error(client->display_resource,
>  				       WL_DISPLAY_ERROR_INVALID_OBJECT,
>  				       "invalid new id %d",
> @@ -931,7 +931,7 @@ wl_client_new_object(struct wl_client *client,
>  {
>  	uint32_t id;
>  
> -	id = wl_map_insert_new(&client->objects, NULL);
> +	id = wl_map_insert_new(&client->objects, 0, NULL);
>  	return wl_client_add_object(client,
>  				    interface, implementation, id, data);
>  
> diff --git a/src/wayland-util.c b/src/wayland-util.c
> index 57f496b..162b352 100644
> --- a/src/wayland-util.c
> +++ b/src/wayland-util.c
> @@ -151,6 +151,10 @@ union map_entry {
>  	void *data;
>  };
>  
> +#define map_entry_is_free(entry) ((entry).next & 0x1)
> +#define map_entry_get_data(entry) ((void *)((entry).next & ~(uintptr_t)0x3))
> +#define map_entry_get_flags(entry) (((entry).next >> 1) & 0x1)
> +
>  WL_EXPORT void
>  wl_map_init(struct wl_map *map, uint32_t side)
>  {
> @@ -166,7 +170,7 @@ wl_map_release(struct wl_map *map)
>  }
>  
>  WL_EXPORT uint32_t
> -wl_map_insert_new(struct wl_map *map, void *data)
> +wl_map_insert_new(struct wl_map *map, uint32_t flags, void *data)
>  {
>  	union map_entry *start, *entry;
>  	struct wl_array *entries;
> @@ -192,12 +196,13 @@ wl_map_insert_new(struct wl_map *map, void *data)
>  	}
>  
>  	entry->data = data;
> +	entry->next |= (flags & 0x1) << 1;
>  
>  	return (entry - start) + base;
>  }
>  
>  WL_EXPORT int
> -wl_map_insert_at(struct wl_map *map, uint32_t i, void *data)
> +wl_map_insert_at(struct wl_map *map, uint32_t flags, uint32_t i, void *data)
>  {
>  	union map_entry *start;
>  	uint32_t count;
> @@ -225,6 +230,7 @@ wl_map_insert_at(struct wl_map *map, uint32_t i, void *data)
>  
>  	start = entries->data;
>  	start[i].data = data;
> +	start[i].next |= (flags & 0x1) << 1;
>  
>  	return 0;
>  }
> @@ -309,12 +315,35 @@ wl_map_lookup(struct wl_map *map, uint32_t i)
>  	start = entries->data;
>  	count = entries->size / sizeof *start;
>  
> -	if (i < count && !(start[i].next & 1))
> -		return start[i].data;
> +	if (i < count && !map_entry_is_free(start[i]))
> +		return map_entry_get_data(start[i]);
>  
>  	return NULL;
>  }
>  
> +WL_EXPORT uint32_t
> +wl_map_lookup_flags(struct wl_map *map, uint32_t i)
> +{
> +	union map_entry *start;
> +	uint32_t count;
> +	struct wl_array *entries;
> +
> +	if (i < WL_SERVER_ID_START) {
> +		entries = &map->client_entries;
> +	} else {
> +		entries = &map->server_entries;
> +		i -= WL_SERVER_ID_START;
> +	}
> +
> +	start = entries->data;
> +	count = entries->size / sizeof *start;
> +
> +	if (i < count && !map_entry_is_free(start[i]))
> +		return map_entry_get_flags(start[i]);
> +
> +	return 0;
> +}
> +
>  static void
>  for_each_helper(struct wl_array *entries, wl_iterator_func_t func, void *data)
>  {
> @@ -324,8 +353,8 @@ for_each_helper(struct wl_array *entries, wl_iterator_func_t func, void *data)
>  	end = (union map_entry *) ((char *) entries->data + entries->size);
>  
>  	for (p = start; p < end; p++)
> -		if (p->data && !(p->next & 1))
> -			func(p->data, data);
> +		if (p->data && !map_entry_is_free(*p))
> +			func(map_entry_get_data(*p), data);
>  }
>  
>  WL_EXPORT void
> -- 
> 1.8.1.4
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list