[PATCH weston v3 5/6] Add API to retrieve and iterate over the resources list of a client
Giulio Camuffo
giuliocamuffo at gmail.com
Thu Aug 11 14:44:30 UTC 2016
2016-08-11 16:34 GMT+02:00 Pekka Paalanen <ppaalanen at gmail.com>:
> On Tue, 9 Aug 2016 12:46:55 +0200
> Giulio Camuffo <giuliocamuffo at gmail.com> wrote:
>
>> To complement on the new resource created signal, this allows to
>> iterate over the existing resources of a client.
>>
>> Signed-off-by: Giulio Camuffo <giulio.camuffo at kdab.com>
>> Reviewed-by: Jonas Ã…dahl <jadahl at gmail.com>
>> ---
>>
>> v3: - add a new wl_iterator_enum to be used instead of the plain int as the
>> return type of the iterator to break the loop
>>
>> src/wayland-private.h | 3 ++-
>> src/wayland-server-core.h | 9 +++++++++
>> src/wayland-server.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++-
>> src/wayland-util.c | 8 ++++++--
>> src/wayland-util.h | 11 +++++++++++
>> 5 files changed, 76 insertions(+), 4 deletions(-)
>>
>> diff --git a/src/wayland-private.h b/src/wayland-private.h
>> index adfbe01..ac712d9 100644
>> --- a/src/wayland-private.h
>> +++ b/src/wayland-private.h
>> @@ -75,7 +75,8 @@ struct wl_map {
>> uint32_t free_list;
>> };
>>
>> -typedef void (*wl_iterator_func_t)(void *element, void *data);
>> +typedef enum wl_iterator_result (*wl_iterator_func_t)(void *element,
>> + void *data);
>>
>> void
>> wl_map_init(struct wl_map *map, uint32_t side);
>> diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h
>> index bb0a989..56e8d80 100644
>> --- a/src/wayland-server-core.h
>> +++ b/src/wayland-server-core.h
>> @@ -216,6 +216,15 @@ void
>> wl_client_add_resource_created_listener(struct wl_client *client,
>> struct wl_listener *listener);
>>
>> +typedef enum wl_iterator_result (*wl_client_for_each_resource_iterator_func_t)(
>> + struct wl_resource *resource,
>> + void *user_data);
>> +
>> +void
>> +wl_client_for_each_resource(struct wl_client *client,
>> + wl_client_for_each_resource_iterator_func_t iterator,
>> + void *user_data);
>> +
>> /** \class wl_listener
>> *
>> * \brief A single listener for Wayland signals
>> diff --git a/src/wayland-server.c b/src/wayland-server.c
>> index 067d8a5..fb44f13 100644
>> --- a/src/wayland-server.c
>> +++ b/src/wayland-server.c
>> @@ -565,7 +565,7 @@ wl_resource_post_no_memory(struct wl_resource *resource)
>> WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
>> }
>>
>> -static void
>> +static enum wl_iterator_result
>> destroy_resource(void *element, void *data)
>> {
>> struct wl_resource *resource = element;
>> @@ -580,6 +580,8 @@ destroy_resource(void *element, void *data)
>>
>> if (!(flags & WL_MAP_ENTRY_LEGACY))
>> free(resource);
>> +
>> + return WL_ITERATOR_CONTINUE;
>> }
>>
>> WL_EXPORT void
>> @@ -1603,6 +1605,51 @@ wl_client_add_resource_created_listener(struct wl_client *client,
>> wl_signal_add(&client->resource_created_signal, listener);
>> }
>>
>> +struct wl_resource_iterator_context {
>> + void *user_data;
>> + wl_client_for_each_resource_iterator_func_t it;
>> +};
>> +
>> +static enum wl_iterator_result
>> +resource_iterator_helper(void *res, void *user_data)
>> +{
>> + struct wl_resource_iterator_context *context = user_data;
>> + struct wl_resource *resource = res;
>> + return context->it(resource, context->user_data);
>> +}
>> +
>> +/** Iterate over all the resources of a client
>> + *
>> + * \param client The client object
>> + * \param iterator The iterator function
>> + * \param user_data The user data pointer
>> + *
>> + * The function pointed by \a iterator will be called for each
>> + * resource owned by the client. The \a user_data will be passed
>> + * as the second argument of the iterator function.
>> + * If the \a iterator function returns \a WL_ITERATOR_CONTINUE the iteration
>> + * will continue, if it returns \a WL_ITERATOR_STOP it will stop.
>
> Hi Giulio
>
> Except it is not guaranteed that it will stop.
>
> If you look at wl_map_for_each(), you see it iterates server and client
> side created objects separately. Trying to stop during the firsts will
> still iterate over the second.
>
> Maybe stopping mid-iterating was not a good idea after all.
>
> Otherwise the patch is good.
>
> What do you want to do?
Oh right. But making it really stop is trivial, so i'll go with that.
Thanks,
Giulio
>
> I'd be ok with just changing the wording in the documentation, but it
> would also be acceptable to me to either not have it stoppable at all
> like you had, or make it really stop guaranteed.
>
>
> Thanks,
> pq
>
>
>> + *
>> + * Creating and destroying resources while iterating is safe, but new
>> + * resources may or may not be picked up by the iterator.
>> + *
>> + * \sa wl_iterator_result
>> + *
>> + * \memberof wl_client
>> + */
>> +WL_EXPORT void
>> +wl_client_for_each_resource(struct wl_client *client,
>> + wl_client_for_each_resource_iterator_func_t iterator,
>> + void *user_data)
>> +{
>> + struct wl_resource_iterator_context context = {
>> + .user_data = user_data,
>> + .it = iterator,
>> + };
>> +
>> + wl_map_for_each(&client->objects, resource_iterator_helper, &context);
>> +}
>> +
>> /** \cond */ /* Deprecated functions below. */
>>
>> uint32_t
>> diff --git a/src/wayland-util.c b/src/wayland-util.c
>> index 7467366..3c38116 100644
>> --- a/src/wayland-util.c
>> +++ b/src/wayland-util.c
>> @@ -363,13 +363,17 @@ static void
>> for_each_helper(struct wl_array *entries, wl_iterator_func_t func, void *data)
>> {
>> union map_entry *start, *end, *p;
>> + enum wl_iterator_result ret;
>>
>> start = entries->data;
>> end = (union map_entry *) ((char *) entries->data + entries->size);
>>
>> for (p = start; p < end; p++)
>> - if (p->data && !map_entry_is_free(*p))
>> - func(map_entry_get_data(*p), data);
>> + if (p->data && !map_entry_is_free(*p)) {
>> + ret = func(map_entry_get_data(*p), data);
>> + if (ret != WL_ITERATOR_CONTINUE)
>> + break;
>> + }
>> }
>>
>> WL_EXPORT void
>> diff --git a/src/wayland-util.h b/src/wayland-util.h
>> index 8da156c..cacc122 100644
>> --- a/src/wayland-util.h
>> +++ b/src/wayland-util.h
>> @@ -311,6 +311,17 @@ typedef int (*wl_dispatcher_func_t)(const void *, void *, uint32_t,
>>
>> typedef void (*wl_log_func_t)(const char *, va_list) WL_PRINTF(1, 0);
>>
>> +/** \enum wl_iterator_result
>> + *
>> + * This enum represents the return value of an iterator function.
>> + */
>> +enum wl_iterator_result {
>> + /** Stop the iteration */
>> + WL_ITERATOR_STOP,
>> + /** Continue the iteration */
>> + WL_ITERATOR_CONTINUE
>> +};
>> +
>> #ifdef __cplusplus
>> }
>> #endif
>
More information about the wayland-devel
mailing list