On Fri, Jul 11, 2014 at 10:22 PM, Yann Ylavic <[email protected]> wrote:
> There also seem to be some doubtful code in apr_skiplist_remove_all(),
> addressed by the following patch :
>
> Index: tables/apr_skiplist.c
> ===================================================================
> --- tables/apr_skiplist.c    (revision 1609655)
> +++ tables/apr_skiplist.c    (working copy)
> @@ -591,16 +591,17 @@ APR_DECLARE(void) apr_skiplist_remove_all(apr_skip
>      m = sl->bottom;
>      while (m) {
>          p = m->next;
> -        if (p && myfree && p->data)
> -            myfree(p->data);
> +        if (myfree && m->data)
> +            myfree(m->data);
>          while (m) {
>              u = m->up;
> -            apr_skiplist_free(sl, p);
> +            apr_skiplist_free(sl, m);
>              m = u;
>          }
>          m = p;
>      }
>      sl->top = sl->bottom = NULL;
> +    sl->topend = sl->bottomend = NULL;
>      sl->height = 0;
>      sl->size = 0;
>  }
>
> Do you agree?

Hmm, no, the initial myfree(p->data) is on purpose, bottom is a fake
node, the real first data are on bottom->next.

Rather this patch :

 Index: tables/apr_skiplist.c
===================================================================
--- tables/apr_skiplist.c    (revision 1609655)
+++ tables/apr_skiplist.c    (working copy)
@@ -595,12 +595,13 @@ APR_DECLARE(void) apr_skiplist_remove_all(apr_skip
             myfree(p->data);
         while (m) {
             u = m->up;
-            apr_skiplist_free(sl, p);
+            apr_skiplist_free(sl, m);
             m = u;
         }
         m = p;
     }
     sl->top = sl->bottom = NULL;
+    sl->topend = sl->bottomend = NULL;
     sl->height = 0;
     sl->size = 0;
 }

to avoid multiple free() on the same node.
(NULLing topend and bottomend is a safety guard since they may be used
elsewhere without top or botton being checked).

Reply via email to