On Tue, 9 Aug 2016 12:46:55 +0200 Giulio Camuffo <giuliocamu...@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.camu...@kdab.com> > Reviewed-by: Jonas Ã…dahl <jad...@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? 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
pgpmTVy0Hj2rT.pgp
Description: OpenPGP digital signature
_______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel