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@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/spice-devel
Attachment:
pgpmsLU5oHExa.pgp
Description: PGP signature
_______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel