[PATCH wayland] Clean up the internals of wl_map

Jason Ekstrand jason at jlekstrand.net
Wed May 29 19:39:18 PDT 2013


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 <jason at 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



More information about the wayland-devel mailing list