X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fforeach%2Fforeach.c;h=879ab86e99c3df3a71a6d0b1dea49297d6818562;hp=70040ee986a5116bb407ea5ebc3ab703d51abd98;hb=6a8d296f9383dd25ec381e2ab136a33823d140e5;hpb=5b115ea9392ca30ce5f0bbeb18389ea9aaea7421;ds=sidebyside diff --git a/ccan/foreach/foreach.c b/ccan/foreach/foreach.c index 70040ee9..879ab86e 100644 --- a/ccan/foreach/foreach.c +++ b/ccan/foreach/foreach.c @@ -1,3 +1,4 @@ +/* Licensed under LGPLv3+ - see LICENSE file for details */ #include #if !HAVE_COMPOUND_LITERALS || !HAVE_FOR_LOOP_DECLARATION #include @@ -12,19 +13,28 @@ struct iter_info { struct list_node list; const void *index; unsigned int i, num; + bool onstack; }; +/* Is pointer still downstack from some other onstack var? */ +static bool on_stack(const void *ptr, const void *onstack) +{ +#if HAVE_STACK_GROWS_UPWARDS + return ptr < onstack; +#else + return ptr > onstack; +#endif +} + static void free_old_iters(const void *index) { struct iter_info *i, *next; list_for_each_safe(&iters, i, next, list) { /* If we're re-using an index, free the old one. - * Otherwise, if it's past i on the stack, it's old. Don't - * assume stack direction, but we know index is downstack. */ + * Otherwise, discard if it's passed off stack. */ if (i->index == index - || (((uintptr_t)index < (uintptr_t)&i) - == ((uintptr_t)&i < (uintptr_t)i->index))) { + || (i->onstack && !on_stack(i->index, &i))) { list_del(&i->list); free(i); } @@ -47,6 +57,7 @@ static struct iter_info *new_iter(const void *index) struct iter_info *info = malloc(sizeof *info); info->index = index; info->i = info->num = 0; + info->onstack = on_stack(index, &info); list_add(&iters, &info->list); return info; };