diff options
author | Jason Ekstrand <jason@jlekstrand.net> | 2013-06-01 17:40:53 -0500 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2013-06-05 00:55:17 -0400 |
commit | 2c7468b868acc334b483fa2617f31bbfb13a3412 (patch) | |
tree | a0aa8ef9c39deeda7a3beb02c27e47450d6e29d4 | |
parent | 28472970df58c69565dbbee2074c434041f9ece4 (diff) |
Add support for flags in the wl_map API and add a WL_MAP_ENTRY_LEGACY flag
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.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
-rw-r--r-- | src/wayland-client.c | 12 | ||||
-rw-r--r-- | src/wayland-private.h | 13 | ||||
-rw-r--r-- | src/wayland-server.c | 12 | ||||
-rw-r--r-- | 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 |