[PATCH i-g-t v7 05/48] lib/igt_kms: Add helper to wait for new connectors

Louis Chauvet
2026-02-23T12:08:52Z

Add list comparison utilities and a new function to wait for new
connectors to appear on the system.

Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
lib/igt_kms.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/igt_kms.h | 6 ++++
2 files changed, 102 insertions(+)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 8876ee8a11f7..514d905fe1fe 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -8170,3 +8170,99 @@ uint32_t igt_get_connector_id_from_mst_path(int drm_fd, const void *mst_path)

return 0;
}
+
+/**
+ * list_contains() - Search an element in the list
+ *
+ * @list: Pointer to the list to search into
+ * @list_len: Length of the list
+ * @value: Value to search in the list
+ *
+ * Returns true if @list contains @value
+ */
+static bool list_contains(const uint32_t *list, int list_len, uint32_t value)
+{
+ igt_assert((!list && list_len == 0) || list);
+ for (int i = 0; i < list_len; i++) {
+ if (list[i] == value)
+ return true;
+ }
+ return false;
+}
+
+/**
+ * get_list_diff() - Compute and return the set difference between two lists
+ *
+ * @list_a: Pointer to the first list to compare
+ * @list_a_len: Length of the first list
+ * @list_b: Pointer to the second list to compare
+ * @list_b_len: Length of the second list
+ * @diff: Out pointer returning a list of items in list_a but not
+ * in list_b. Can be NULL to only count the elements.
+ *
+ * Returns the number of element which are in @list_a but not in @list_b.
+ */
+int
+get_list_diff(const uint32_t *list_a, int list_a_len, const uint32_t *list_b, int list_b_len,
+ uint32_t **diff)
+{
+ int diff_len = 0;
+
+ igt_assert((!list_a && list_a_len == 0) || list_a);
+ igt_assert((!list_b && list_b_len == 0) || list_b);
+
+ if (diff)
+ *diff = malloc(sizeof(**diff));
+
+ for (int i = 0; i < list_a_len; i++) {
+ if (!list_contains(list_b, list_b_len, list_a[i])) {
+ if (diff) {
+ *diff = reallocarray(*diff, diff_len + 1, sizeof(**diff));
+ igt_assert(*diff);
+ (*diff)[diff_len] = list_a[i];
+ }
+
+ diff_len++;
+ }
+ }
+
+ return diff_len;
+}
+
+/**
+ * kms_wait_for_new_connectors() - Wait for new connector to appear
+ *
+ * @newly_connected: Out pointer returning the list of connectors currently
+ * found connected
+ * @already_connected: Input pointer to list of connectors previously
+ * connected
+ * @already_connected_count: Length of @already_connected
+ * @drm_fd: DRM file descriptor
+ *
+ * Returns the number of connectors not in @already_connected and currently
+ * found connected.
+ */
+int kms_wait_for_new_connectors(uint32_t **newly_connected,
+ const uint32_t *already_connected,
+ int already_connected_count, int drm_fd)
+{
+ int newly_connected_count;
+ struct timespec start, end;
+
+ igt_assert(newly_connected);
+ igt_assert(drm_fd);
+
+ clock_gettime(CLOCK_MONOTONIC, &start);
+ clock_gettime(CLOCK_MONOTONIC, &end);
+ do {
+ if (*newly_connected)
+ free(*newly_connected);
+ newly_connected_count = igt_get_connected_connectors(drm_fd, newly_connected);
+ clock_gettime(CLOCK_MONOTONIC, &end);
+ } while (get_list_diff(*newly_connected, newly_connected_count,
+ already_connected, already_connected_count,
+ NULL) == 0 &&
+ igt_time_elapsed(&start, &end) <= igt_default_display_detect_timeout());
+
+ return newly_connected_count;
+}
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 52b62252683b..a0b36efd8ebb 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -1326,4 +1326,10 @@ drmModeConnectorPtr igt_get_connector_from_name(int drm_fd, const char *port_nam
uint32_t igt_get_connector_id_from_name(int drm_fd, const char *port_name);
uint32_t igt_get_connector_id_from_mst_path(int drm_fd, const void *mst_path);

+int kms_wait_for_new_connectors(uint32_t **newly_connected,
+ const uint32_t *already_connected,
+ int already_connected_count, int drm_fd);
+int
+get_list_diff(const uint32_t *list_a, int list_a_len, const uint32_t *list_b, int list_b_len,
+ uint32_t **diff);
#endif /* __IGT_KMS_H__ */

--
2.52.0