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