aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/connection.c11
-rw-r--r--src/wayland-client-core.h10
-rw-r--r--src/wayland-client.c96
-rw-r--r--src/wayland-private.h3
-rw-r--r--src/wayland-server.c2
-rw-r--r--tests/queue-test.c112
6 files changed, 218 insertions, 16 deletions
diff --git a/src/connection.c b/src/connection.c
index a6ad410..b89166f 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -1283,7 +1283,8 @@ wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection)
void
wl_closure_print(struct wl_closure *closure, struct wl_object *target,
- int send, int discarded, uint32_t (*n_parse)(union wl_argument *arg))
+ int send, int discarded, uint32_t (*n_parse)(union wl_argument *arg),
+ const char *queue_name)
{
int i;
struct argument_details arg;
@@ -1302,8 +1303,12 @@ wl_closure_print(struct wl_closure *closure, struct wl_object *target,
clock_gettime(CLOCK_REALTIME, &tp);
time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
- fprintf(f, "[%7u.%03u] %s%s%s#%u.%s(",
- time / 1000, time % 1000,
+ fprintf(f, "[%7u.%03u] ", time / 1000, time % 1000);
+
+ if (queue_name)
+ fprintf(f, "{%s} ", queue_name);
+
+ fprintf(f, "%s%s%s#%u.%s(",
discarded ? "discarded " : "",
send ? " -> " : "",
target->interface->name, target->id,
diff --git a/src/wayland-client-core.h b/src/wayland-client-core.h
index af50f1e..20b2a3b 100644
--- a/src/wayland-client-core.h
+++ b/src/wayland-client-core.h
@@ -225,6 +225,12 @@ wl_proxy_get_display(struct wl_proxy *proxy);
void
wl_proxy_set_queue(struct wl_proxy *proxy, struct wl_event_queue *queue);
+struct wl_event_queue *
+wl_proxy_get_queue(const struct wl_proxy *proxy);
+
+const char *
+wl_event_queue_get_name(const struct wl_event_queue *queue);
+
struct wl_display *
wl_display_connect(const char *name);
@@ -272,6 +278,10 @@ wl_display_roundtrip(struct wl_display *display);
struct wl_event_queue *
wl_display_create_queue(struct wl_display *display);
+struct wl_event_queue *
+wl_display_create_queue_with_name(struct wl_display *display,
+ const char *name);
+
int
wl_display_prepare_read_queue(struct wl_display *display,
struct wl_event_queue *queue);
diff --git a/src/wayland-client.c b/src/wayland-client.c
index 489f0a8..94438e3 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -77,6 +77,7 @@ struct wl_event_queue {
struct wl_list event_list;
struct wl_list proxy_list; /**< struct wl_proxy::queue_link */
struct wl_display *display;
+ char *name;
};
struct wl_display {
@@ -220,11 +221,15 @@ display_protocol_error(struct wl_display *display, uint32_t code,
}
static void
-wl_event_queue_init(struct wl_event_queue *queue, struct wl_display *display)
+wl_event_queue_init(struct wl_event_queue *queue,
+ struct wl_display *display,
+ const char *name)
{
wl_list_init(&queue->event_list);
wl_list_init(&queue->proxy_list);
queue->display = display;
+ if (name)
+ queue->name = strdup(name);
}
static void
@@ -305,8 +310,15 @@ wl_event_queue_release(struct wl_event_queue *queue)
struct wl_proxy *proxy, *tmp;
if (queue != &queue->display->default_queue) {
- wl_log("warning: queue %p destroyed while proxies "
- "still attached:\n", queue);
+ if (queue->name) {
+ wl_log("warning: queue \"%s\" "
+ "%p destroyed while proxies "
+ "still attached:\n", queue->name, queue);
+ } else {
+ wl_log("warning: queue "
+ "%p destroyed while proxies "
+ "still attached:\n", queue);
+ }
}
wl_list_for_each_safe(proxy, tmp, &queue->proxy_list,
@@ -350,6 +362,7 @@ wl_event_queue_destroy(struct wl_event_queue *queue)
pthread_mutex_lock(&display->mutex);
wl_event_queue_release(queue);
+ free(queue->name);
free(queue);
pthread_mutex_unlock(&display->mutex);
}
@@ -371,7 +384,30 @@ wl_display_create_queue(struct wl_display *display)
if (queue == NULL)
return NULL;
- wl_event_queue_init(queue, display);
+ wl_event_queue_init(queue, display, NULL);
+
+ return queue;
+}
+
+/** Create a new event queue for this display and give it a name
+ *
+ * \param display The display context object
+ * \param name A human readable queue name
+ * \return A new event queue associated with this display or NULL on
+ * failure.
+ *
+ * \memberof wl_display
+ */
+WL_EXPORT struct wl_event_queue *
+wl_display_create_queue_with_name(struct wl_display *display, const char *name)
+{
+ struct wl_event_queue *queue;
+
+ queue = zalloc(sizeof *queue);
+ if (queue == NULL)
+ return NULL;
+
+ wl_event_queue_init(queue, display, name);
return queue;
}
@@ -885,8 +921,13 @@ wl_proxy_marshal_array_flags(struct wl_proxy *proxy, uint32_t opcode,
goto err_unlock;
}
- if (debug_client)
- wl_closure_print(closure, &proxy->object, true, false, NULL);
+ if (debug_client) {
+ struct wl_event_queue *queue;
+
+ queue = wl_proxy_get_queue(proxy);
+ wl_closure_print(closure, &proxy->object, true, false, NULL,
+ wl_event_queue_get_name(queue));
+ }
if (wl_closure_send(closure, proxy->display->connection)) {
wl_log("Error sending request: %s\n", strerror(errno));
@@ -1188,8 +1229,8 @@ wl_display_connect_to_fd(int fd)
display->fd = fd;
wl_map_init(&display->objects, WL_MAP_CLIENT_SIDE);
- wl_event_queue_init(&display->default_queue, display);
- wl_event_queue_init(&display->display_queue, display);
+ wl_event_queue_init(&display->default_queue, display, "Default Queue");
+ wl_event_queue_init(&display->display_queue, display, "Display Queue");
pthread_mutex_init(&display->mutex, NULL);
pthread_cond_init(&display->reader_cond, NULL);
display->reader_count = 0;
@@ -1321,7 +1362,9 @@ wl_display_disconnect(struct wl_display *display)
wl_map_for_each(&display->objects, free_zombies, NULL);
wl_map_release(&display->objects);
wl_event_queue_release(&display->default_queue);
+ free(display->default_queue.name);
wl_event_queue_release(&display->display_queue);
+ free(display->display_queue.name);
pthread_mutex_destroy(&display->mutex);
pthread_cond_destroy(&display->reader_cond);
close(display->fd);
@@ -1611,7 +1654,8 @@ dispatch_event(struct wl_display *display, struct wl_event_queue *queue)
proxy_destroyed = !!(proxy->flags & WL_PROXY_FLAG_DESTROYED);
if (proxy_destroyed) {
if (debug_client)
- wl_closure_print(closure, &proxy->object, false, true, id_from_object);
+ wl_closure_print(closure, &proxy->object, false, true,
+ id_from_object, queue->name);
destroy_queued_closure(closure);
return;
}
@@ -1620,13 +1664,15 @@ dispatch_event(struct wl_display *display, struct wl_event_queue *queue)
if (proxy->dispatcher) {
if (debug_client)
- wl_closure_print(closure, &proxy->object, false, false, id_from_object);
+ wl_closure_print(closure, &proxy->object, false, false,
+ id_from_object, queue->name);
wl_closure_dispatch(closure, proxy->dispatcher,
&proxy->object, opcode);
} else if (proxy->object.implementation) {
if (debug_client)
- wl_closure_print(closure, &proxy->object, false, false, id_from_object);
+ wl_closure_print(closure, &proxy->object, false, false,
+ id_from_object, queue->name);
wl_closure_invoke(closure, WL_CLOSURE_INVOKE_CLIENT,
&proxy->object, opcode, proxy->user_data);
@@ -2399,6 +2445,34 @@ wl_proxy_set_queue(struct wl_proxy *proxy, struct wl_event_queue *queue)
pthread_mutex_unlock(&proxy->display->mutex);
}
+/** Get a proxy's event queue
+ *
+ * \param proxy The proxy to query
+ *
+ * Return the event queue
+ */
+WL_EXPORT struct wl_event_queue *
+wl_proxy_get_queue(const struct wl_proxy *proxy)
+{
+ return proxy->queue;
+
+}
+/** Get the name of an event queue
+ *
+ * \param queue The queue to query
+ *
+ * Return the human readable name for the event queue
+ *
+ * This may be NULL if no name has been set.
+ *
+ * \memberof wl_proxy
+ */
+WL_EXPORT const char *
+wl_event_queue_get_name(const struct wl_event_queue *queue)
+{
+ return queue->name;
+}
+
/** Create a proxy wrapper for making queue assignments thread-safe
*
* \param proxy The proxy object to be wrapped
diff --git a/src/wayland-private.h b/src/wayland-private.h
index 9274f1b..6b50658 100644
--- a/src/wayland-private.h
+++ b/src/wayland-private.h
@@ -213,7 +213,8 @@ wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection);
void
wl_closure_print(struct wl_closure *closure,
struct wl_object *target, int send, int discarded,
- uint32_t (*n_parse)(union wl_argument *arg));
+ uint32_t (*n_parse)(union wl_argument *arg),
+ const char *queue_name);
void
wl_closure_destroy(struct wl_closure *closure);
diff --git a/src/wayland-server.c b/src/wayland-server.c
index e784ef6..1534114 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -157,7 +157,7 @@ log_closure(struct wl_resource *resource,
struct wl_protocol_logger_message message;
if (debug_server)
- wl_closure_print(closure, object, send, false, NULL);
+ wl_closure_print(closure, object, send, false, NULL, NULL);
if (!wl_list_empty(&display->protocol_loggers)) {
message.resource = resource;
diff --git a/tests/queue-test.c b/tests/queue-test.c
index 6562139..cb61a85 100644
--- a/tests/queue-test.c
+++ b/tests/queue-test.c
@@ -472,6 +472,106 @@ client_test_queue_destroy_default_with_attached_proxies(void)
}
static void
+check_queue_name(struct wl_proxy *proxy, const char *name)
+{
+ struct wl_event_queue *queue;
+ const char *queue_name;
+
+ queue = wl_proxy_get_queue(proxy);
+ queue_name = wl_event_queue_get_name(queue);
+ if (!name)
+ assert(!queue_name);
+ else
+ assert(strcmp(queue_name, name) == 0);
+}
+
+static struct wl_callback *
+roundtrip_named_queue_nonblock(struct wl_display *display,
+ struct wl_event_queue *queue,
+ const char *name)
+{
+ struct wl_callback *callback;
+ struct wl_display *wrapped_display = NULL;
+
+ if (queue) {
+ wrapped_display = wl_proxy_create_wrapper(display);
+ assert(wrapped_display);
+ wl_proxy_set_queue((struct wl_proxy *) wrapped_display, queue);
+ check_queue_name((struct wl_proxy *) wrapped_display, name);
+
+ callback = wl_display_sync(wrapped_display);
+ } else
+ callback = wl_display_sync(display);
+
+ check_queue_name((struct wl_proxy *) callback, name);
+
+ if (wrapped_display)
+ wl_proxy_wrapper_destroy(wrapped_display);
+
+ assert(callback != NULL);
+
+ return callback;
+}
+
+static void
+client_test_queue_names(void)
+{
+ struct wl_event_queue *queue1, *queue2, *queue3;
+ struct wl_display *display;
+ struct wl_callback *callback1, *callback2, *callback3, *callback4;
+ struct wl_event_queue *default_queue;
+ char *log;
+ size_t log_len;
+ const char *default_queue_name;
+
+ display = wl_display_connect(NULL);
+ assert(display);
+
+ default_queue = wl_proxy_get_queue((struct wl_proxy *) display);
+ default_queue_name = wl_event_queue_get_name(default_queue);
+ assert(strcmp(default_queue_name, "Default Queue") == 0);
+
+ /* Create some event queues both with and without names. */
+ queue1 = wl_display_create_queue_with_name(display, "First");
+ assert(queue1);
+
+ queue2 = wl_display_create_queue_with_name(display, "Second");
+ assert(queue2);
+
+ queue3 = wl_display_create_queue(display);
+ assert(queue3);
+
+ /* Create some requests and ensure their queues have the expected
+ * names.
+ */
+ callback1 = roundtrip_named_queue_nonblock(display, queue1, "First");
+ callback2 = roundtrip_named_queue_nonblock(display, queue2, "Second");
+ callback3 = roundtrip_named_queue_nonblock(display, queue3, NULL);
+ callback4 = roundtrip_named_queue_nonblock(display, NULL, "Default Queue");
+
+ /* Destroy one queue with proxies still attached so we can verify
+ * that the queue name is in the log message. */
+ wl_event_queue_destroy(queue2);
+ log = map_file(client_log_fd, &log_len);
+ assert(strstr(log, "Second"));
+
+ /* There's no reason for the First queue name to be present. */
+ assert(!strstr(log, "First"));
+
+ munmap(log, log_len);
+
+ wl_callback_destroy(callback1);
+ wl_callback_destroy(callback2);
+ wl_callback_destroy(callback3);
+ wl_callback_destroy(callback4);
+
+ wl_event_queue_destroy(queue1);
+ wl_event_queue_destroy(queue3);
+
+ wl_display_disconnect(display);
+}
+
+static void
dummy_bind(struct wl_client *client,
void *data, uint32_t version, uint32_t id)
{
@@ -597,3 +697,15 @@ TEST(queue_destroy_default_with_attached_proxies)
display_destroy(d);
}
+
+TEST(queue_names)
+{
+ struct display *d = display_create();
+
+ test_set_timeout(2);
+
+ client_create_noarg(d, client_test_queue_names);
+ display_run(d);
+
+ display_destroy(d);
+}