The doc for apr_hash_first states:
"There is no restriction on adding or deleting hash entries during an iteration(...)"
This is not true for a constelation as follows:
If the table iterator (apr_hash_index_t struct) hi->next points to an entry, which is beeing deleted between two calls of apr_hash_next(), then the second apr_hash_next() will still return the deleted entry.
The following patch tries to solve this by marking the deleted entry by setting the value to NULL.
- gunter
Index: apr/tables/apr_hash.c
===================================================================
RCS file: /home/cvspublic/apr/tables/apr_hash.c,v
retrieving revision 1.35
diff -u -r1.35 apr_hash.c
--- apr/tables/apr_hash.c 13 Jan 2003 18:52:07 -0000 1.35
+++ apr/tables/apr_hash.c 2 May 2003 11:45:24 -0000
@@ -148,6 +148,16 @@
APR_DECLARE(apr_hash_index_t *) apr_hash_next(apr_hash_index_t *hi)
{
hi->this = hi->next;
+ // if the found entry has been deleted in the meantime,
+ // forward to next one in the chain.
+ if (hi->this) {
+ while (hi->this->val == NULL) {
+ hi->this = hi->this->next ;
+ if (!hi->this)
+ break ;
+ }
+ }
+
while (!hi->this) {
if (hi->index > hi->ht->max)
return NULL;
@@ -352,6 +362,7 @@
apr_hash_entry_t **hep;
hep = find_entry(ht, key, klen, val);
if (*hep) {
+ (*hep)->val = val;
if (!val) {
/* delete entry */
*hep = (*hep)->next;
@@ -359,7 +370,7 @@
}
else {
/* replace entry */
- (*hep)->val = val;
+
/* check that the collision rate isn't too high */
if (ht->count > ht->max) {
expand_array(ht);
