[Spice-devel] [server PATCH 7/8] red_worker: use a generic SAFE_FOREACH macro

Christophe Fergeau cfergeau at redhat.com
Mon Jul 8 03:57:58 PDT 2013


On Mon, Jul 08, 2013 at 01:32:29PM +0300, Uri Lublin wrote:
> Introduce SAFE_FOREACH macro
> 
> Make other safe iterators use SAFE_FOREACH

There's already a RING_FOREACH_SAFE() macro in spice-common/ring.h, could
it be useful here?

Christophe

> ---
>  server/red_worker.c |   64 ++++++++++++++++++++++----------------------------
>  1 files changed, 28 insertions(+), 36 deletions(-)
> 
> diff --git a/server/red_worker.c b/server/red_worker.c
> index 1f239c5..7351064 100644
> --- a/server/red_worker.c
> +++ b/server/red_worker.c
> @@ -1113,24 +1113,25 @@ static inline uint64_t red_now(void);
>   *  given a channel, iterate over it's clients
>   */
>  
> +/* a generic safe for loop macro  */
> +#define SAFE_FOREACH(link, next, cond, ring, data, get_data)               \
> +    for ((((link) = ((cond) ? ring_get_head(ring) : NULL)), \
> +          ((next) = ((link) ? ring_next((ring), (link)) : NULL)),          \
> +          ((data) = ((link)? (get_data) : NULL)));                         \
> +         (link);                                                           \
> +         (((link) = (next)),                                               \
> +          ((next) = ((link) ? ring_next((ring), (link)) : NULL)),          \
> +          ((data) = ((link)? (get_data) : NULL))))
> +
> +#define LINK_TO_RCC(ptr) SPICE_CONTAINEROF(ptr, RedChannelClient, channel_link)
>  #define RCC_FOREACH_SAFE(link, next, rcc, channel) \
> -    for (link = ring_get_head(&(channel)->clients),                         \
> -         rcc = SPICE_CONTAINEROF(link, RedChannelClient, channel_link),     \
> -         (next) = (link) ? ring_next(&(channel)->clients, (link)) : NULL;      \
> -            (link);                                            \
> -            (link) = (next),                                   \
> -            (next) = (link) ? ring_next(&(channel)->clients, (link)) : NULL,    \
> -            rcc = SPICE_CONTAINEROF(link, RedChannelClient, channel_link))
> +    SAFE_FOREACH(link, next, channel,  &(channel)->clients, rcc, LINK_TO_RCC(link))
>  
> +
> +#define LINK_TO_DCC(ptr) SPICE_CONTAINEROF(ptr, DisplayChannelClient,  \
> +                                      common.base.channel_link)
>  #define DCC_FOREACH_SAFE(link, next, dcc, channel)                       \
> -    for ((link) = ((channel) ? ring_get_head(&(channel)->clients) : NULL), \
> -           (next) = ((link) ? ring_next(&(channel)->clients, (link)) : NULL), \
> -           (dcc) = ((link) ? SPICE_CONTAINEROF((link), DisplayChannelClient, \
> -                                          common.base.channel_link) : NULL); \
> -         (link);                                                        \
> -         (link) = (next),                                               \
> -           (next) = ((link) ? ring_next(&(channel)->clients, (link)) : NULL), \
> -           (dcc) = SPICE_CONTAINEROF((link), DisplayChannelClient, common.base.channel_link))
> +    SAFE_FOREACH(link, next, channel,  &(channel)->clients, dcc, LINK_TO_DCC(link))
>  
>  
>  #define WORKER_FOREACH_DCC_SAFE(worker, link, next, dcc)      \
> @@ -1139,32 +1140,23 @@ static inline uint64_t red_now(void);
>                   (&(worker)->display_channel->common.base) : NULL))
>  
>  
> +#define LINK_TO_DPI(ptr) SPICE_CONTAINEROF((ptr), DrawablePipeItem, base)
>  #define DRAWABLE_FOREACH_DPI_SAFE(drawable, link, next, dpi)          \
> -    for (link = (drawable) ? ring_get_head(&(drawable)->pipes) : NULL,\
> -         (next) = ((link) ? ring_next(&(drawable)->pipes, (link)) : NULL), \
> -         dpi = (link) ? SPICE_CONTAINEROF((link), DrawablePipeItem, base) : NULL; \
> -         (link);\
> -         (link) = (next), \
> -           (next) = ((link) ? ring_next(&(drawable)->pipes, (link)) : NULL), \
> -           dpi = (link) ? SPICE_CONTAINEROF((link), DrawablePipeItem, base) : NULL)
> +    SAFE_FOREACH(link, next, drawable,  &(drawable)->pipes, dpi, LINK_TO_DPI(link))
> +
>  
> +#define LINK_TO_GLZ(ptr) SPICE_CONTAINEROF((ptr), RedGlzDrawable, \
> +                                           drawable_link)
>  #define DRAWABLE_FOREACH_GLZ_SAFE(drawable, link, next, glz) \
> -    for (link = (drawable) ? ring_get_head(&drawable->glz_ring) : NULL,\
> -        next = (link) ? ring_next(&drawable->glz_ring, link) : NULL,\
> -        glz = (link) ? SPICE_CONTAINEROF((link), RedGlzDrawable, drawable_link) : NULL;\
> -        (link);\
> -        (link) = (next),\
> -        (next) = (link) ? ring_next(&drawable->glz_ring, (link)) : NULL,\
> -        glz = (link) ? SPICE_CONTAINEROF((link), RedGlzDrawable, drawable_link) : NULL)
> +    SAFE_FOREACH(link, next, drawable, &(drawable)->glz_ring, glz, LINK_TO_GLZ(link))
> +
>  
> +#define LINK_TO_CCC(ptr) SPICE_CONTAINEROF(ptr, CommonChannelClient, \
> +                                           base.channel_link)
>  #define CCC_FOREACH_SAFE(link, next, ccc, channel)       \
> -    for (link = ring_get_head(&(channel)->clients),\
> -           (next) = (link) ? ring_next(&(channel)->clients, (link)) : NULL, \
> -           ccc = SPICE_CONTAINEROF(link, CommonChannelClient, base.channel_link);\
> -         (link);                              \
> -         (link) = (next), \
> -           (next) = (link) ? ring_next(&(channel)->clients, (link)) : NULL, \
> -           ccc = SPICE_CONTAINEROF(link, CommonChannelClient, base.channel_link))
> +    SAFE_FOREACH(link, next, channel, &(channel)->clients, ccc, LINK_TO_CCC(link))
> +
> +
>  
>  #define DCC_TO_WORKER(dcc) \
>      (SPICE_CONTAINEROF((dcc)->common.base.channel, CommonChannel, base)->worker)
> -- 
> 1.7.1
> 
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/spice-devel/attachments/20130708/5314e30f/attachment-0001.pgp>


More information about the Spice-devel mailing list