[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