This commit cleans up the internals of wl_map by splitting it into two
wl_simple_maps.  This both makes the internals cleaner and also fixes potential
issues with having a single free_list for both sides of the map.

Signed-off-by: Jason Ekstrand <ja...@jlekstrand.net>
---
 src/wayland-private.h |  10 ++-
 src/wayland-util.c    | 172 ++++++++++++++++++++++++++------------------------
 2 files changed, 97 insertions(+), 85 deletions(-)

diff --git a/src/wayland-private.h b/src/wayland-private.h
index c4ce6b0..a733a96 100644
--- a/src/wayland-private.h
+++ b/src/wayland-private.h
@@ -41,12 +41,16 @@
 #define WL_SERVER_ID_START 0xff000000
 #define WL_CLOSURE_MAX_ARGS 20
 
-struct wl_map {
-       struct wl_array client_entries;
-       struct wl_array server_entries;
+struct wl_simple_map {
+       struct wl_array entries;
        uint32_t free_list;
 };
 
+struct wl_map {
+       struct wl_simple_map client_map;
+       struct wl_simple_map server_map;
+};
+
 typedef void (*wl_iterator_func_t)(void *element, void *data);
 
 void wl_map_init(struct wl_map *map);
diff --git a/src/wayland-util.c b/src/wayland-util.c
index 598ab42..b8831b8 100644
--- a/src/wayland-util.c
+++ b/src/wayland-util.c
@@ -151,102 +151,64 @@ union map_entry {
        void *data;
 };
 
-WL_EXPORT void
-wl_map_init(struct wl_map *map)
-{
-       memset(map, 0, sizeof *map);
-}
-
-WL_EXPORT void
-wl_map_release(struct wl_map *map)
-{
-       wl_array_release(&map->client_entries);
-       wl_array_release(&map->server_entries);
-}
-
-WL_EXPORT uint32_t
-wl_map_insert_new(struct wl_map *map, uint32_t side, void *data)
+static uint32_t
+wl_simple_map_insert_new(struct wl_simple_map *map, void *data)
 {
        union map_entry *start, *entry;
-       struct wl_array *entries;
-       uint32_t base;
-
-       if (side == WL_MAP_CLIENT_SIDE) {
-               entries = &map->client_entries;
-               base = 0;
-       } else {
-               entries = &map->server_entries;
-               base = WL_SERVER_ID_START;
-       }
-
        if (map->free_list) {
-               start = entries->data;
+               start = map->entries.data;
                entry = &start[map->free_list >> 1];
                map->free_list = entry->next;
        } else {
-               entry = wl_array_add(entries, sizeof *entry);
+               entry = wl_array_add(&map->entries, sizeof *entry);
                if (!entry)
                        return 0;
-               start = entries->data;
+               start = map->entries.data;
        }
 
        entry->data = data;
 
-       return (entry - start) + base;
+       return (entry - start);
 }
 
-WL_EXPORT int
-wl_map_insert_at(struct wl_map *map, uint32_t i, void *data)
+static int
+wl_simple_map_insert_at(struct wl_simple_map *map, uint32_t i, void *data)
 {
        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;
-       }
 
-       count = entries->size / sizeof *start;
+       count = map->entries.size / sizeof *start;
        if (count < i)
                return -1;
 
        if (count == i)
-               wl_array_add(entries, sizeof *start);
+               if (!wl_array_add(&map->entries, sizeof *start))
+                       return -1;
 
-       start = entries->data;
+       start = map->entries.data;
        start[i].data = data;
 
        return 0;
 }
 
-WL_EXPORT int
-wl_map_reserve_new(struct wl_map *map, uint32_t i)
+static int
+wl_simple_map_reserve_new(struct wl_simple_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;
-       }
-
-       count = entries->size / sizeof *start;
+       count = map->entries.size / sizeof *start;
 
        if (count < i)
                return -1;
 
        if (count == i) {
-               wl_array_add(entries, sizeof *start);
-               start = entries->data;
+               if (!wl_array_add(&map->entries, sizeof *start))
+                       return -1;
+               start = map->entries.data;
                start[i].data = NULL;
        } else {
-               start = entries->data;
+               start = map->entries.data;
                if (start[i].data != NULL) {
                        return -1;
                }
@@ -255,40 +217,24 @@ wl_map_reserve_new(struct wl_map *map, uint32_t i)
        return 0;
 }
 
-WL_EXPORT void
-wl_map_remove(struct wl_map *map, uint32_t i)
+static void
+wl_simple_map_remove(struct wl_simple_map *map, uint32_t i)
 {
        union map_entry *start;
-       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;
+       start = map->entries.data;
        start[i].next = map->free_list;
        map->free_list = (i << 1) | 1;
 }
 
-WL_EXPORT void *
-wl_map_lookup(struct wl_map *map, uint32_t i)
+void *
+wl_simple_map_lookup(struct wl_simple_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;
+       start = map->entries.data;
+       count = map->entries.size / sizeof *start;
 
        if (i < count && !(start[i].next & 1))
                return start[i].data;
@@ -296,6 +242,68 @@ wl_map_lookup(struct wl_map *map, uint32_t i)
        return NULL;
 }
 
+WL_EXPORT void
+wl_map_init(struct wl_map *map)
+{
+       memset(map, 0, sizeof *map);
+}
+
+WL_EXPORT void
+wl_map_release(struct wl_map *map)
+{
+       wl_array_release(&map->client_map.entries);
+       wl_array_release(&map->server_map.entries);
+}
+
+WL_EXPORT uint32_t
+wl_map_insert_new(struct wl_map *map, uint32_t side, void *data)
+{
+       if (side == WL_MAP_CLIENT_SIDE)
+               return wl_simple_map_insert_new(&map->client_map, data);
+       else
+               return wl_simple_map_insert_new(&map->server_map, data)
+                       + WL_SERVER_ID_START;
+}
+
+WL_EXPORT int
+wl_map_insert_at(struct wl_map *map, uint32_t i, void *data)
+{
+       if (i < WL_SERVER_ID_START)
+               return wl_simple_map_insert_at(&map->client_map, i, data);
+       else
+               return wl_simple_map_insert_at(&map->server_map,
+                                              i - WL_SERVER_ID_START, data);
+}
+
+WL_EXPORT int
+wl_map_reserve_new(struct wl_map *map, uint32_t i)
+{
+       if (i < WL_SERVER_ID_START)
+               return wl_simple_map_reserve_new(&map->client_map, i);
+       else
+               return wl_simple_map_reserve_new(&map->server_map,
+                                                i - WL_SERVER_ID_START);
+}
+
+WL_EXPORT void
+wl_map_remove(struct wl_map *map, uint32_t i)
+{
+       if (i < WL_SERVER_ID_START)
+               wl_simple_map_remove(&map->client_map, i);
+       else
+               wl_simple_map_remove(&map->server_map, i - WL_SERVER_ID_START);
+}
+
+WL_EXPORT void *
+wl_map_lookup(struct wl_map *map, uint32_t i)
+{
+       if (i < WL_SERVER_ID_START)
+               return wl_simple_map_lookup(&map->client_map, i);
+       else
+               return wl_simple_map_lookup(&map->server_map,
+                                           i - WL_SERVER_ID_START);
+}
+
 static void
 for_each_helper(struct wl_array *entries, wl_iterator_func_t func, void *data)
 {
@@ -312,8 +320,8 @@ for_each_helper(struct wl_array *entries, 
wl_iterator_func_t func, void *data)
 WL_EXPORT void
 wl_map_for_each(struct wl_map *map, wl_iterator_func_t func, void *data)
 {
-       for_each_helper(&map->client_entries, func, data);
-       for_each_helper(&map->server_entries, func, data);
+       for_each_helper(&map->client_map.entries, func, data);
+       for_each_helper(&map->server_map.entries, func, data);
 }
 
 static void
-- 
1.8.1.4

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to