From 5df73f847e3a0650f49b0f6cd0dc38249571ebbf Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Thu, 15 Feb 2007 15:23:24 +0000 Subject: [PATCH] Fixups. git-svn-id: file:///svn/unbound/trunk@107 be551aaa-1e26-0410-a405-d3ace91eadb9 --- doc/Changelog | 2 ++ services/outside_network.c | 20 +++++++++++++------- services/outside_network.h | 2 ++ util/rbtree.c | 19 +++++++++++++++++++ util/rbtree.h | 11 +++++++++++ 5 files changed, 47 insertions(+), 7 deletions(-) diff --git a/doc/Changelog b/doc/Changelog index 73770dfb0..91c86c91e 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -2,6 +2,8 @@ - port to FreeBSD 4.11 Dec Alpha. Also works on Solaris 10 sparc64, Solaris 9, FreeBSD 6, Linux i386 and OSX powerpc. - malloc rndstate, so that it is aligned for access. + - fixed rbtree cleanup with postorder traverse. + - fixed pending messages are deleted when handled. 14 February 2007: Wouter - Included configure.ac changes from ldns. diff --git a/services/outside_network.c b/services/outside_network.c index 8435f5c2b..9c95f6978 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -149,6 +149,7 @@ outnet_udp_cb(struct comm_point* c, void* arg, int error, comm_timer_disable(p->timer); log_info("outnet handle udp reply"); (void)(*p->cb)(p->c, p->cb_arg, NETEVENT_NOERROR, NULL); + pending_delete(outnet, p); return 0; } @@ -262,6 +263,7 @@ pending_udp_timer_cb(void *arg) /* it timed out */ log_info("timeout udp"); (void)(*p->cb)(p->c, p->cb_arg, NETEVENT_TIMEOUT, NULL); + pending_delete(p->outnet, p); } struct outside_network* @@ -332,6 +334,15 @@ outside_network_create(struct comm_base *base, size_t bufsize, return outnet; } +/** helper pending delete */ +static void +pending_node_del(rbnode_t* node, void* arg) +{ + struct pending* pend = (struct pending*)node; + struct outside_network* outnet = (struct outside_network*)arg; + pending_delete(outnet, pend); +} + void outside_network_delete(struct outside_network* outnet) { @@ -339,13 +350,7 @@ outside_network_delete(struct outside_network* outnet) return; /* check every element, since we can be called on malloc error */ if(outnet->pending) { - struct pending *p, *np; - p = (struct pending*)rbtree_first(outnet->pending); - while(p && (rbnode_t*)p!=RBTREE_NULL) { - np = (struct pending*)rbtree_next((rbnode_t*)p); - pending_delete(NULL, p); - p = np; - } + traverse_postorder(outnet->pending, pending_node_del, outnet); free(outnet->pending); } if(outnet->udp_buff) @@ -406,6 +411,7 @@ new_pending(struct outside_network* outnet, ldns_buffer* packet, pend->addrlen = addrlen; pend->cb = callback; pend->cb_arg = callback_arg; + pend->outnet = outnet; /* insert in tree */ pend->node.key = pend; diff --git a/services/outside_network.h b/services/outside_network.h index 524dcaa78..36f9dec20 100644 --- a/services/outside_network.h +++ b/services/outside_network.h @@ -100,6 +100,8 @@ struct pending { comm_point_callback_t* cb; /** callback user argument */ void* cb_arg; + /** the outside network it is part of */ + struct outside_network* outnet; }; /** diff --git a/util/rbtree.c b/util/rbtree.c index 9b1730fe6..02d978d5e 100644 --- a/util/rbtree.c +++ b/util/rbtree.c @@ -589,3 +589,22 @@ rbtree_previous(rbnode_t *node) } return node; } + +/** recursive descent traverse. */ +static void +traverse_post(void (*func)(rbnode_t*, void*), void* arg, rbnode_t* node) +{ + if(!node || node == RBTREE_NULL) + return; + /* recurse */ + traverse_post(func, arg, node->left); + traverse_post(func, arg, node->right); + /* call user func */ + (*func)(node, arg); +} + +void +traverse_postorder(rbtree_t* tree, void (*func)(rbnode_t*, void*), void* arg) +{ + traverse_post(func, arg, tree->root); +} diff --git a/util/rbtree.h b/util/rbtree.h index aaa176995..8b5b7acd9 100644 --- a/util/rbtree.h +++ b/util/rbtree.h @@ -179,4 +179,15 @@ rbnode_t *rbtree_previous(rbnode_t *rbtree); (rbnode_t*)node != RBTREE_NULL; \ node = (type)rbtree_next((rbnode_t*)node)) +/** + * Call function for all elements in the redblack tree, such that + * leaf elements are called before parent elements. So that all + * elements can be safely free()d. + * @param tree: the tree + * @param func: function called with element and user arg. + * @param arg: user argument. + */ +void traverse_postorder(rbtree_t* tree, void (*func)(rbnode_t*, void*), + void* arg); + #endif /* UTIL_RBTREE_H_ */ -- 2.47.2