make iterating with pa_idxset_next() robust in regards to idxset modifications

This commit is contained in:
Lennart Poettering 2009-02-03 02:15:36 +01:00
parent f8190be2e6
commit c61ad2a706

View file

@ -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);
hash = *idx % NBUCKETS;
if (!(e = index_scan(s, hash, *idx)))
if (*idx == PA_IDXSET_INVALID)
return NULL;
if (!e->iterate_next) {
hash = *idx % NBUCKETS;
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;
}
}
*idx = PA_IDXSET_INVALID;
return NULL;
}
e = e->iterate_next;
*idx = e->idx;
return e->data;
}
unsigned pa_idxset_size(pa_idxset*s) {