summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2009-02-03 02:15:36 +0100
committerLennart Poettering <lennart@poettering.net>2009-02-03 02:15:36 +0100
commitc61ad2a70619fc2fcec209838b37e047df2d1d2d (patch)
treedcc878571f3cab68b34df120b2637d6dc15e2d93
parentf8190be2e675ebf5ebe5750a74818b02969539bb (diff)
make iterating with pa_idxset_next() robust in regards to idxset modifications
-rw-r--r--src/pulsecore/idxset.c42
1 files 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) {