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 <ja...@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel