[PATCH wayland 1/3] wayland-server: Add a numerical id per client

Rob Bradford robert.bradford at intel.com
Mon Jul 22 09:30:50 PDT 2013


From: Rob Bradford <rob at linux.intel.com>

Assign each client a numerical id when the client is created for the
display. We do not want the client ids to be sparse so that they can be
used for space efficient lookups in the compositor; so when the client
is destroyed we release the id either into the next counter if it was
the most recent client or into a free pool. The next id is provided
using a most recently freed strategy.

Since the structure is opaque this change also adds an accessor function
for the client to retrieve the id.
---
 src/wayland-server.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 src/wayland-server.h |  1 +
 2 files changed, 46 insertions(+)

diff --git a/src/wayland-server.c b/src/wayland-server.c
index 0a6e112..d3f396a 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -77,6 +77,7 @@ struct wl_client {
 	struct wl_signal destroy_signal;
 	struct ucred ucred;
 	int error;
+	uint32_t id;
 };
 
 struct wl_display {
@@ -92,6 +93,8 @@ struct wl_display {
 	struct wl_list client_list;
 
 	struct wl_signal destroy_signal;
+	struct wl_array free_client_ids;
+	uint32_t next_client_id;
 };
 
 struct wl_global {
@@ -335,6 +338,26 @@ static void
 bind_display(struct wl_client *client,
 	     void *data, uint32_t version, uint32_t id);
 
+static uint32_t
+get_next_client_id (struct wl_display *display)
+{
+	uint32_t id = 0;
+	uint32_t *p;
+
+	if (display->free_client_ids.size > 0) {
+		p = display->free_client_ids.data +
+		    display->free_client_ids.size -
+		    sizeof(uint32_t);
+		id = *p;
+		display->free_client_ids.size -= sizeof(uint32_t);
+		return id;
+	}
+
+	id = display->next_client_id;
+	display->next_client_id++;
+	return id;
+}
+
 WL_EXPORT struct wl_client *
 wl_client_create(struct wl_display *display, int fd)
 {
@@ -376,6 +399,8 @@ wl_client_create(struct wl_display *display, int fd)
 
 	wl_list_insert(display->client_list.prev, &client->link);
 
+	client->id = get_next_client_id(display);
+
 	return client;
 
 err_map:
@@ -576,9 +601,24 @@ wl_client_destroy(struct wl_client *client)
 	wl_event_source_remove(client->source);
 	wl_connection_destroy(client->connection);
 	wl_list_remove(&client->link);
+
+	if (client->id == client->display->next_client_id - 1) {
+		client->display->next_client_id--;
+	} else {
+		uint32_t *p;
+		p = wl_array_add(&client->display->free_client_ids, sizeof *p);
+		*p = client->id;
+	}
+
 	free(client);
 }
 
+WL_EXPORT uint32_t
+wl_client_get_id(struct wl_client *client)
+{
+	return client->id;
+}
+
 static void
 registry_bind(struct wl_client *client,
 	      struct wl_resource *resource, uint32_t name,
@@ -714,6 +754,9 @@ wl_display_create(void)
 
 	wl_signal_init(&display->destroy_signal);
 
+	wl_array_init(&display->free_client_ids);
+	display->next_client_id = 1;
+
 	display->id = 1;
 	display->serial = 0;
 
@@ -748,6 +791,8 @@ wl_display_destroy(struct wl_display *display)
 	wl_list_for_each_safe(global, gnext, &display->global_list, link)
 		free(global);
 
+	wl_array_release(&display->free_client_ids);
+
 	free(display);
 }
 
diff --git a/src/wayland-server.h b/src/wayland-server.h
index 9e16d0e..5109530 100644
--- a/src/wayland-server.h
+++ b/src/wayland-server.h
@@ -128,6 +128,7 @@ struct wl_resource *
 wl_client_get_object(struct wl_client *client, uint32_t id);
 void
 wl_client_post_no_memory(struct wl_client *client);
+uint32_t wl_client_get_id(struct wl_client *client);
 
 struct wl_listener {
 	struct wl_list link;
-- 
1.8.3.1



More information about the wayland-devel mailing list