Make rbtree_loop() and rbtree_loop_reverse() safe against removal of an entry.
authorAndre Noll <maan@systemlinux.org>
Mon, 24 Sep 2007 16:08:13 +0000 (18:08 +0200)
committerAndre Noll <maan@systemlinux.org>
Mon, 24 Sep 2007 16:08:13 +0000 (18:08 +0200)
Also, fix the documentation of osl_rbtree_loop() which claimed that an
osl_rbtree_loop_func takes two void pointers which is not true any more.

osl.c

diff --git a/osl.c b/osl.c
index ab3b8de..48f25a1 100644 (file)
--- a/osl.c
+++ b/osl.c
@@ -1697,9 +1697,12 @@ int osl_get_row(const struct osl_table *t, unsigned col_num,
 static int rbtree_loop(struct osl_column *col,  void *private_data,
                osl_rbtree_loop_func *func)
 {
-       struct rb_node *n;
+       struct rb_node *n, *tmp;
 
-       for (n = rb_first(&col->rbtree); n; n = rb_next(n)) {
+       /* this for-loop is safe against removal of an entry */
+       for (n = rb_first(&col->rbtree), tmp = n? rb_next(n) : NULL;
+                       n;
+                       n = tmp, tmp = tmp? rb_next(tmp) : NULL) {
                struct osl_row *r = get_row_pointer(n, col->rbtree_num);
                int ret = func(r, private_data);
                if (ret < 0)
@@ -1711,9 +1714,12 @@ static int rbtree_loop(struct osl_column *col,  void *private_data,
 static int rbtree_loop_reverse(struct osl_column *col,  void *private_data,
                osl_rbtree_loop_func *func)
 {
-       struct rb_node *n;
+       struct rb_node *n, *tmp;
 
-       for (n = rb_last(&col->rbtree); n; n = rb_prev(n)) {
+       /* safe against removal of an entry */
+       for (n = rb_last(&col->rbtree), tmp = n? rb_prev(n) : NULL;
+                       n;
+                       n = tmp, tmp = tmp? rb_prev(tmp) : NULL) {
                struct osl_row *r = get_row_pointer(n, col->rbtree_num);
                int ret = func(r, private_data);
                if (ret < 0)
@@ -1733,9 +1739,9 @@ static int rbtree_loop_reverse(struct osl_column *col,  void *private_data,
  * This function does an in-order walk of the rbtree associated with \a
  * col_num. It is an error if the \p OSL_RBTREE flag is not set for this
  * column. For each node in the rbtree, the given function \a func is called
- * with two \p void* pointers as arguments: The first argument points to the
+ * with two pointers as arguments: The first osl_row* argument points to the
  * row that contains the object corresponding to the rbtree node currently
- * traversed, and the \a private_data pointer is passed to \a func as the
+ * traversed, and the \a private_data pointer is passed verbatim to \a func as the
  * second argument. The loop terminates either if \a func returns a negative
  * value, or if all nodes of the tree have been visited.
  *