summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Ådahl <jadahl@gmail.com>2015-12-24 12:41:46 +0800
committerJonas Ådahl <jadahl@gmail.com>2016-01-16 16:37:36 +0800
commit7efe8fbd89b069947d616ba187732ce2c2804839 (patch)
tree174da1d577c2c559f4d11ddddfb27c91e396c46a
parent242617c3161f7d50a592ab21607301aacd4e8f8c (diff)
downloadwayland-7efe8fbd89b069947d616ba187732ce2c2804839.tar.gz
tests: Synchronize client termination in idle callback
We currently wait for clients in the wl_client destroy signal, which is called before the client is destructed and the socket is closed. If test clients rely on being closed due to the socket being closed we'd dead lock. Avoid this by synchronizing in an idle task that is called after the client is fully destroyed. Signed-off-by: Jonas Ådahl <jadahl@gmail.com> Reviewed-by: Daniel Stone <daniels@collabora.com>
-rw-r--r--tests/test-compositor.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/tests/test-compositor.c b/tests/test-compositor.c
index 296db3b..965074b 100644
--- a/tests/test-compositor.c
+++ b/tests/test-compositor.c
@@ -91,17 +91,13 @@ get_socket_name(void)
return retval;
}
-/**
- * Check client's state and terminate display when all clients exited
- */
static void
-client_destroyed(struct wl_listener *listener, void *data)
+handle_client_destroy(void *data)
{
+ struct client_info *ci = data;
struct display *d;
- struct client_info *ci;
siginfo_t status;
- ci = wl_container_of(listener, ci, destroy_listener);
d = ci->display;
assert(waitid(P_PID, ci->pid, &status, WEXITED) != -1);
@@ -132,6 +128,25 @@ client_destroyed(struct wl_listener *listener, void *data)
* clients. In the case that the test would go through
* the clients list manually, zero out the wl_client as a sign
* that the client is not running anymore */
+}
+
+/**
+ * Check client's state and terminate display when all clients exited
+ */
+static void
+client_destroyed(struct wl_listener *listener, void *data)
+{
+ struct client_info *ci;
+ struct display *d;
+ struct wl_event_loop *loop;
+
+ /* Wait for client in an idle handler to avoid blocking the actual
+ * client destruction (fd close etc. */
+ ci = wl_container_of(listener, ci, destroy_listener);
+ d = ci->display;
+ loop = wl_display_get_event_loop(d->wl_display);
+ wl_event_loop_add_idle(loop, handle_client_destroy, ci);
+
ci->wl_client = NULL;
}