<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Jun 3, 2013 at 4:36 AM, Ander Conselvan de Oliveira <span dir="ltr"><<a href="mailto:conselvan2@gmail.com" target="_blank">conselvan2@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On 06/02/2013 01:40 AM, Jason Ekstrand wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The implementation in this commit allows for one bit worth of flags. If<br>
more flags are desired at a future date, then the wl_map implementation<br>
will have to change but the wl_map API will not.<br>
</blockquote>
<br></div>
I couldn't find a description of what WL_MAP_ENTRY_LEGACY is supposed to mean anywhere in the patch. Would be good to document that in the commit message and/or near the enum definition. And maybe this explanation would also make clear why flags are necessary.<br>
</blockquote><div><br></div><div>The purpose is so that we can deprecate the internals of wl_resource. We need a way (that doesn't involve changing wl_resource) to flag a resource as being a legacy version 1.0 resource so we can special-case it. We can do this by building it into wl_map. Perhaps there should be a comment in there to that effect.<br>
<br></div><div>--Jason Ekstrand<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Cheers,<br>
Ander<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Signed-off-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>><br>
---<br>
src/wayland-client.c | 12 ++++++------<br>
src/wayland-private.h | 13 +++++++++++--<br>
src/wayland-server.c | 12 ++++++------<br>
src/wayland-util.c | 41 ++++++++++++++++++++++++++++++<u></u>+++++------<br>
4 files changed, 58 insertions(+), 20 deletions(-)<br>
<br>
diff --git a/src/wayland-client.c b/src/wayland-client.c<br>
index 0f5e093..bea73e0 100644<br>
--- a/src/wayland-client.c<br>
+++ b/src/wayland-client.c<br>
@@ -226,7 +226,7 @@ wl_proxy_create(struct wl_proxy *factory, const struct wl_interface *interface)<br>
proxy->refcount = 1;<br>
<br>
pthread_mutex_lock(&display-><u></u>mutex);<br>
- proxy-><a href="http://object.id" target="_blank">object.id</a> = wl_map_insert_new(&display-><u></u>objects, proxy);<br>
+ proxy-><a href="http://object.id" target="_blank">object.id</a> = wl_map_insert_new(&display-><u></u>objects, 0, proxy);<br>
pthread_mutex_unlock(&display-<u></u>>mutex);<br>
<br>
return proxy;<br>
@@ -252,7 +252,7 @@ wl_proxy_create_for_id(struct wl_proxy *factory,<br>
proxy->flags = 0;<br>
proxy->refcount = 1;<br>
<br>
- wl_map_insert_at(&display-><u></u>objects, id, proxy);<br>
+ wl_map_insert_at(&display-><u></u>objects, 0, id, proxy);<br>
<br>
return proxy;<br>
}<br>
@@ -273,10 +273,10 @@ wl_proxy_destroy(struct wl_proxy *proxy)<br>
if (proxy->flags & WL_PROXY_FLAG_ID_DELETED)<br>
wl_map_remove(&proxy->display-<u></u>>objects, proxy-><a href="http://object.id" target="_blank">object.id</a>);<br>
else if (proxy-><a href="http://object.id" target="_blank">object.id</a> < WL_SERVER_ID_START)<br>
- wl_map_insert_at(&proxy-><u></u>display->objects,<br>
+ wl_map_insert_at(&proxy-><u></u>display->objects, 0,<br>
proxy-><a href="http://object.id" target="_blank">object.id</a>, WL_ZOMBIE_OBJECT);<br>
else<br>
- wl_map_insert_at(&proxy-><u></u>display->objects,<br>
+ wl_map_insert_at(&proxy-><u></u>display->objects, 0,<br>
proxy-><a href="http://object.id" target="_blank">object.id</a>, NULL);<br>
<br>
<br>
@@ -522,11 +522,11 @@ wl_display_connect_to_fd(int fd)<br>
wl_list_init(&display->event_<u></u>queue_list);<br>
pthread_mutex_init(&display-><u></u>mutex, NULL);<br>
<br>
- wl_map_insert_new(&display-><u></u>objects, NULL);<br>
+ wl_map_insert_new(&display-><u></u>objects, 0, NULL);<br>
<br>
display->proxy.object.<u></u>interface = &wl_display_interface;<br>
display-><a href="http://proxy.object.id" target="_blank">proxy.object.id</a> =<br>
- wl_map_insert_new(&display-><u></u>objects, display);<br>
+ wl_map_insert_new(&display-><u></u>objects, 0, display);<br>
display->proxy.display = display;<br>
display->proxy.object.<u></u>implementation = (void(**)(void)) &display_listener;<br>
display->proxy.user_data = display;<br>
diff --git a/src/wayland-private.h b/src/wayland-private.h<br>
index 270b470..a648538 100644<br>
--- a/src/wayland-private.h<br>
+++ b/src/wayland-private.h<br>
@@ -41,6 +41,14 @@<br>
#define WL_SERVER_ID_START 0xff000000<br>
#define WL_CLOSURE_MAX_ARGS 20<br>
<br>
+/* Flags for wl_map_insert_new and wl_map_insert_at. Flags can be queried with<br>
+ * wl_map_lookup_flags. The current implementation has room for 1 bit worth of<br>
+ * flags. If more flags are ever added, the implementation of wl_map will have<br>
+ * to change to allow for new flags */<br>
+enum wl_map_entry_flags {<br>
+ WL_MAP_ENTRY_LEGACY = (1 << 0)<br>
+};<br>
+<br>
struct wl_map {<br>
struct wl_array client_entries;<br>
struct wl_array server_entries;<br>
@@ -52,11 +60,12 @@ typedef void (*wl_iterator_func_t)(void *element, void *data);<br>
<br>
void wl_map_init(struct wl_map *map, uint32_t side);<br>
void wl_map_release(struct wl_map *map);<br>
-uint32_t wl_map_insert_new(struct wl_map *map, void *data);<br>
-int wl_map_insert_at(struct wl_map *map, uint32_t i, void *data);<br>
+uint32_t wl_map_insert_new(struct wl_map *map, uint32_t flags, void *data);<br>
+int wl_map_insert_at(struct wl_map *map, uint32_t flags, uint32_t i, void *data);<br>
int wl_map_reserve_new(struct wl_map *map, uint32_t i);<br>
void wl_map_remove(struct wl_map *map, uint32_t i);<br>
void *wl_map_lookup(struct wl_map *map, uint32_t i);<br>
+uint32_t wl_map_lookup_flags(struct wl_map *map, uint32_t i);<br>
void wl_map_for_each(struct wl_map *map, wl_iterator_func_t func, void *data);<br>
<br>
struct wl_connection;<br>
diff --git a/src/wayland-server.c b/src/wayland-server.c<br>
index c96be56..2d13d9d 100644<br>
--- a/src/wayland-server.c<br>
+++ b/src/wayland-server.c<br>
@@ -338,7 +338,7 @@ wl_client_create(struct wl_display *display, int fd)<br>
<br>
wl_map_init(&client->objects, WL_MAP_SERVER_SIDE);<br>
<br>
- if (wl_map_insert_at(&client-><u></u>objects, 0, NULL) < 0)<br>
+ if (wl_map_insert_at(&client-><u></u>objects, 0, 0, NULL) < 0)<br>
goto err_map;<br>
<br>
wl_signal_init(&client-><u></u>destroy_signal);<br>
@@ -379,8 +379,8 @@ wl_client_add_resource(struct wl_client *client,<br>
{<br>
if (resource-><a href="http://object.id" target="_blank">object.id</a> == 0) {<br>
resource-><a href="http://object.id" target="_blank">object.id</a> =<br>
- wl_map_insert_new(&client-><u></u>objects, resource);<br>
- } else if (wl_map_insert_at(&client-><u></u>objects,<br>
+ wl_map_insert_new(&client-><u></u>objects, 0, resource);<br>
+ } else if (wl_map_insert_at(&client-><u></u>objects, 0,<br>
resource-><a href="http://object.id" target="_blank">object.id</a>, resource) < 0) {<br>
wl_resource_post_error(client-<u></u>>display_resource,<br>
WL_DISPLAY_ERROR_INVALID_<u></u>OBJECT,<br>
@@ -433,7 +433,7 @@ wl_resource_destroy(struct wl_resource *resource)<br>
wl_resource_queue_event(<u></u>client->display_resource,<br>
WL_DISPLAY_DELETE_ID, id);<br>
}<br>
- wl_map_insert_at(&client-><u></u>objects, id, NULL);<br>
+ wl_map_insert_at(&client-><u></u>objects, 0, id, NULL);<br>
} else {<br>
wl_map_remove(&client-><u></u>objects, id);<br>
}<br>
@@ -912,7 +912,7 @@ wl_client_add_object(struct wl_client *client,<br>
resource->client = client;<br>
resource->destroy = (void *) free;<br>
<br>
- if (wl_map_insert_at(&client-><u></u>objects, resource-><a href="http://object.id" target="_blank">object.id</a>, resource) < 0) {<br>
+ if (wl_map_insert_at(&client-><u></u>objects, 0, resource-><a href="http://object.id" target="_blank">object.id</a>, resource) < 0) {<br>
wl_resource_post_error(client-<u></u>>display_resource,<br>
WL_DISPLAY_ERROR_INVALID_<u></u>OBJECT,<br>
"invalid new id %d",<br>
@@ -931,7 +931,7 @@ wl_client_new_object(struct wl_client *client,<br>
{<br>
uint32_t id;<br>
<br>
- id = wl_map_insert_new(&client-><u></u>objects, NULL);<br>
+ id = wl_map_insert_new(&client-><u></u>objects, 0, NULL);<br>
return wl_client_add_object(client,<br>
interface, implementation, id, data);<br>
<br>
diff --git a/src/wayland-util.c b/src/wayland-util.c<br>
index 57f496b..162b352 100644<br>
--- a/src/wayland-util.c<br>
+++ b/src/wayland-util.c<br>
@@ -151,6 +151,10 @@ union map_entry {<br>
void *data;<br>
};<br>
<br>
+#define map_entry_is_free(entry) ((entry).next & 0x1)<br>
+#define map_entry_get_data(entry) ((void *)((entry).next & ~(uintptr_t)0x3))<br>
+#define map_entry_get_flags(entry) (((entry).next >> 1) & 0x1)<br>
+<br>
WL_EXPORT void<br>
wl_map_init(struct wl_map *map, uint32_t side)<br>
{<br>
@@ -166,7 +170,7 @@ wl_map_release(struct wl_map *map)<br>
}<br>
<br>
WL_EXPORT uint32_t<br>
-wl_map_insert_new(struct wl_map *map, void *data)<br>
+wl_map_insert_new(struct wl_map *map, uint32_t flags, void *data)<br>
{<br>
union map_entry *start, *entry;<br>
struct wl_array *entries;<br>
@@ -192,12 +196,13 @@ wl_map_insert_new(struct wl_map *map, void *data)<br>
}<br>
<br>
entry->data = data;<br>
+ entry->next |= (flags & 0x1) << 1;<br>
<br>
return (entry - start) + base;<br>
}<br>
<br>
WL_EXPORT int<br>
-wl_map_insert_at(struct wl_map *map, uint32_t i, void *data)<br>
+wl_map_insert_at(struct wl_map *map, uint32_t flags, uint32_t i, void *data)<br>
{<br>
union map_entry *start;<br>
uint32_t count;<br>
@@ -225,6 +230,7 @@ wl_map_insert_at(struct wl_map *map, uint32_t i, void *data)<br>
<br>
start = entries->data;<br>
start[i].data = data;<br>
+ start[i].next |= (flags & 0x1) << 1;<br>
<br>
return 0;<br>
}<br>
@@ -309,12 +315,35 @@ wl_map_lookup(struct wl_map *map, uint32_t i)<br>
start = entries->data;<br>
count = entries->size / sizeof *start;<br>
<br>
- if (i < count && !(start[i].next & 1))<br>
- return start[i].data;<br>
+ if (i < count && !map_entry_is_free(start[i]))<br>
+ return map_entry_get_data(start[i]);<br>
<br>
return NULL;<br>
}<br>
<br>
+WL_EXPORT uint32_t<br>
+wl_map_lookup_flags(struct wl_map *map, uint32_t i)<br>
+{<br>
+ union map_entry *start;<br>
+ uint32_t count;<br>
+ struct wl_array *entries;<br>
+<br>
+ if (i < WL_SERVER_ID_START) {<br>
+ entries = &map->client_entries;<br>
+ } else {<br>
+ entries = &map->server_entries;<br>
+ i -= WL_SERVER_ID_START;<br>
+ }<br>
+<br>
+ start = entries->data;<br>
+ count = entries->size / sizeof *start;<br>
+<br>
+ if (i < count && !map_entry_is_free(start[i]))<br>
+ return map_entry_get_flags(start[i]);<br>
+<br>
+ return 0;<br>
+}<br>
+<br>
static void<br>
for_each_helper(struct wl_array *entries, wl_iterator_func_t func, void *data)<br>
{<br>
@@ -324,8 +353,8 @@ for_each_helper(struct wl_array *entries, wl_iterator_func_t func, void *data)<br>
end = (union map_entry *) ((char *) entries->data + entries->size);<br>
<br>
for (p = start; p < end; p++)<br>
- if (p->data && !(p->next & 1))<br>
- func(p->data, data);<br>
+ if (p->data && !map_entry_is_free(*p))<br>
+ func(map_entry_get_data(*p), data);<br>
}<br>
<br>
WL_EXPORT void<br>
<br>
</blockquote>
<br>
</div></div></blockquote></div><br></div></div>