[PATCH] server: Add API to disable the event queue

Neil Roberts neil at linux.intel.com
Fri Sep 13 08:12:27 PDT 2013


Adds wl_client_disable_queue and wl_client_enable_queue. When the
queue is disabled, flushing the client will cause it to send all of
the data regardless of whether ‘want_flush’ is set on the connection.

The ‘want_flush’ mechanism is used to implement the event queue.
Normally queued events are only sent once a later event is posted
without the queue. It looks like this is currently only used in order
to delay sending the buffer release events until a frame callback
event is emitted at the same time to avoid waking up the clients more
often than necessary.

The problem with that is that if a client isn't using the frame
callbacks and instead is throttling itself to the buffer release
events then the queue will never get flushed and the client will wait
forever. With this new API the compositor can recognise when a client
doesn't have a frame callback installed and explicitly disable the
queue so that it will get the buffer release events immediately.
---
 src/connection.c      | 16 +++++++++++++++-
 src/wayland-private.h |  2 ++
 src/wayland-server.c  | 12 ++++++++++++
 src/wayland-server.h  |  2 ++
 4 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/src/connection.c b/src/connection.c
index 451b93e..5e26af1 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -59,6 +59,7 @@ struct wl_connection {
 	struct wl_buffer fds_in, fds_out;
 	int fd;
 	int want_flush;
+	int enable_queue;
 };
 
 static void
@@ -157,6 +158,7 @@ wl_connection_create(int fd)
 		return NULL;
 	memset(connection, 0, sizeof *connection);
 	connection->fd = fd;
+	connection->enable_queue = 1;
 
 	return connection;
 }
@@ -265,7 +267,7 @@ wl_connection_flush(struct wl_connection *connection)
 	int len = 0, count, clen;
 	uint32_t tail;
 
-	if (!connection->want_flush)
+	if (connection->enable_queue && !connection->want_flush)
 		return 0;
 
 	tail = connection->out.tail;
@@ -372,6 +374,18 @@ wl_connection_queue(struct wl_connection *connection,
 	return 0;
 }
 
+void
+wl_connection_enable_queue(struct wl_connection *connection)
+{
+	connection->enable_queue = 1;
+}
+
+void
+wl_connection_disable_queue(struct wl_connection *connection)
+{
+	connection->enable_queue = 0;
+}
+
 static int
 wl_message_count_arrays(const struct wl_message *message)
 {
diff --git a/src/wayland-private.h b/src/wayland-private.h
index 67e8783..6247cee 100644
--- a/src/wayland-private.h
+++ b/src/wayland-private.h
@@ -92,6 +92,8 @@ void wl_connection_consume(struct wl_connection *connection, size_t size);
 
 int wl_connection_flush(struct wl_connection *connection);
 int wl_connection_read(struct wl_connection *connection);
+void wl_connection_enable_queue(struct wl_connection *connection);
+void wl_connection_disable_queue(struct wl_connection *connection);
 
 int wl_connection_write(struct wl_connection *connection, const void *data, size_t count);
 int wl_connection_queue(struct wl_connection *connection,
diff --git a/src/wayland-server.c b/src/wayland-server.c
index d7c58b9..6d37137 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -591,6 +591,18 @@ wl_client_get_destroy_listener(struct wl_client *client,
 }
 
 WL_EXPORT void
+wl_client_enable_queue(struct wl_client *client)
+{
+	wl_connection_enable_queue(client->connection);
+}
+
+WL_EXPORT void
+wl_client_disable_queue(struct wl_client *client)
+{
+	wl_connection_disable_queue(client->connection);
+}
+
+WL_EXPORT void
 wl_client_destroy(struct wl_client *client)
 {
 	uint32_t serial = 0;
diff --git a/src/wayland-server.h b/src/wayland-server.h
index 67f3bdd..95a1ae2 100644
--- a/src/wayland-server.h
+++ b/src/wayland-server.h
@@ -123,6 +123,8 @@ void wl_client_add_destroy_listener(struct wl_client *client,
 				    struct wl_listener *listener);
 struct wl_listener *wl_client_get_destroy_listener(struct wl_client *client,
 						   wl_notify_func_t notify);
+void wl_client_enable_queue(struct wl_client *client);
+void wl_client_disable_queue(struct wl_client *client);
 
 struct wl_resource *
 wl_client_get_object(struct wl_client *client, uint32_t id);
-- 
1.8.3.1



More information about the wayland-devel mailing list