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);

Reply via email to