From c61ad2a70619fc2fcec209838b37e047df2d1d2d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 3 Feb 2009 02:15:36 +0100 Subject: make iterating with pa_idxset_next() robust in regards to idxset modifications --- src/pulsecore/idxset.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/src/pulsecore/idxset.c b/src/pulsecore/idxset.c index 24a28db7..352ac977 100644 --- a/src/pulsecore/idxset.c +++ b/src/pulsecore/idxset.c @@ -386,8 +386,11 @@ void* pa_idxset_steal_first(pa_idxset *s, uint32_t *idx) { void* pa_idxset_first(pa_idxset *s, uint32_t *idx) { pa_assert(s); - if (!s->iterate_list_head) + if (!s->iterate_list_head) { + if (idx) + *idx = PA_IDXSET_INVALID; return NULL; + } if (idx) *idx = s->iterate_list_head->idx; @@ -402,20 +405,41 @@ void *pa_idxset_next(pa_idxset *s, uint32_t *idx) { pa_assert(s); pa_assert(idx); + if (*idx == PA_IDXSET_INVALID) + return NULL; + hash = *idx % NBUCKETS; - if (!(e = index_scan(s, hash, *idx))) - return NULL; + if ((e = index_scan(s, hash, *idx))) { + + e = e->iterate_next; + + if (e) { + *idx = e->idx; + return e->data; + } else { + *idx = PA_IDXSET_INVALID; + return NULL; + } + + } else { + + /* If the entry passed doesn't exist anymore we try to find + * the next following */ + + for ((*idx)++; *idx < s->current_index; (*idx)++) { + + hash = *idx % NBUCKETS; + + if ((e = index_scan(s, hash, *idx))) { + *idx = e->idx; + return e->data; + } + } - if (!e->iterate_next) { *idx = PA_IDXSET_INVALID; return NULL; } - - e = e->iterate_next; - - *idx = e->idx; - return e->data; } unsigned pa_idxset_size(pa_idxset*s) { -- cgit