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

Kamil Konieczny
2026-02-26T16:17:48Z

Hi Louis,
On 2026-02-23 at 13:09:12 +0100, Louis Chauvet wrote:
> 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)

Why do you name it a list? It is an array. Do we need abstract data types
in igt, like igt_array? Also, you keep only uint32 as values.

There is already a list ADT in igt, maybe you could reuse and extend it?

Regards,
Kamil

> +{
> + 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
>