From 99636d1589e9e311967dcdcba41bd51c3c1f5de8 Mon Sep 17 00:00:00 2001 From: Bart Polot Date: Wed, 21 Sep 2011 12:59:59 +0000 Subject: [PATCH] Renamed functions, make valgrind stop complaining about memory leaks by explicitly freeing stuff before exit --- src/mesh/gnunet-service-mesh.c | 4 +- src/mesh/mesh_tunnel_tree.c | 74 +++++++++++++++++++++++++++++----- src/mesh/mesh_tunnel_tree.h | 22 ++++++---- src/mesh/test_mesh_path_api.c | 39 +++++++++--------- 4 files changed, 98 insertions(+), 41 deletions(-) diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c index f927c3666..7ac577476 100644 --- a/src/mesh/gnunet-service-mesh.c +++ b/src/mesh/gnunet-service-mesh.c @@ -1041,7 +1041,7 @@ tunnel_add_peer (struct MeshTunnel *t, struct MeshPeerInfo *peer) } p = p->next; } - tunnel_add_path (t->tree, best_p, ¬ify_peer_disconnected); + tree_add_path (t->tree, best_p, ¬ify_peer_disconnected); if (GNUNET_SCHEDULER_NO_TASK == t->path_refresh_task) t->path_refresh_task = GNUNET_SCHEDULER_add_delayed (t->tree->refresh, &path_refresh, t); @@ -2177,7 +2177,7 @@ dht_get_type_handler (void *cls, struct GNUNET_TIME_Absolute exp, p = path_build_from_dht (get_path, put_path); path_add_to_peer (peer_info, p); tunnel_add_peer(t, peer_info); - p = tunnel_get_path_to_peer(t->tree, peer_info->id); + p = tree_get_path_to_peer(t->tree, peer_info->id); #if MESH_DEBUG GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: new route for tunnel 0x%x found, has %u hops\n", diff --git a/src/mesh/mesh_tunnel_tree.c b/src/mesh/mesh_tunnel_tree.c index ad9e9032a..30aaeadb3 100644 --- a/src/mesh/mesh_tunnel_tree.c +++ b/src/mesh/mesh_tunnel_tree.c @@ -129,7 +129,7 @@ path_get_cost (struct MeshTunnelTree *t, struct MeshPeerPath *path) * @return Pointer to the node of the peer. NULL if not found. */ struct MeshTunnelTreeNode * -tunnel_find_peer (struct MeshTunnelTreeNode *root, GNUNET_PEER_Id peer_id) +tree_find_peer (struct MeshTunnelTreeNode *root, GNUNET_PEER_Id peer_id) { struct MeshTunnelTreeNode *n; unsigned int i; @@ -138,7 +138,7 @@ tunnel_find_peer (struct MeshTunnelTreeNode *root, GNUNET_PEER_Id peer_id) return root; for (i = 0; i < root->nchildren; i++) { - n = tunnel_find_peer (&root->children[i], peer_id); + n = tree_find_peer (&root->children[i], peer_id); if (NULL != n) return n; } @@ -153,7 +153,7 @@ tunnel_find_peer (struct MeshTunnelTreeNode *root, GNUNET_PEER_Id peer_id) * @param cb Callback to use to notify about disconnected peers. */ void -tunnel_mark_peers_disconnected (struct MeshTunnelTreeNode *parent, +tree_mark_peers_disconnected (struct MeshTunnelTreeNode *parent, MeshNodeDisconnectCB cb) { unsigned int i; @@ -165,7 +165,7 @@ tunnel_mark_peers_disconnected (struct MeshTunnelTreeNode *parent, parent->status = MESH_PEER_RECONNECTING; for (i = 0; i < parent->nchildren; i++) { - tunnel_mark_peers_disconnected (&parent->children[i], cb); + tree_mark_peers_disconnected (&parent->children[i], cb); } // struct GNUNET_MESH_PeerControl msg; // if (NULL == parent->t->client) @@ -195,7 +195,7 @@ tunnel_mark_peers_disconnected (struct MeshTunnelTreeNode *parent, * @return pointer to the pathless node, NULL on error */ struct MeshTunnelTreeNode * -tunnel_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id, +tree_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id, MeshNodeDisconnectCB cb) { struct MeshTunnelTreeNode *parent; @@ -204,7 +204,7 @@ tunnel_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id, if (peer_id == t->root->peer) return NULL; - node = n = tunnel_find_peer (t->me, peer_id); + node = n = tree_find_peer (t->me, peer_id); if (NULL == n) return NULL; parent = n->parent; @@ -222,7 +222,7 @@ tunnel_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id, parent->nchildren--; parent->children = GNUNET_realloc (parent->children, parent->nchildren); - tunnel_mark_peers_disconnected (node, cb); + tree_mark_peers_disconnected (node, cb); return node; } @@ -239,13 +239,13 @@ tunnel_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id, * Path must be destroyed afterwards. */ struct MeshPeerPath * -tunnel_get_path_to_peer(struct MeshTunnelTree *t, GNUNET_PEER_Id peer) +tree_get_path_to_peer(struct MeshTunnelTree *t, GNUNET_PEER_Id peer) { struct MeshTunnelTreeNode *n; struct MeshPeerPath *p; GNUNET_PEER_Id myid = t->me->peer; - n = tunnel_find_peer(t->me, peer); + n = tree_find_peer(t->me, peer); p = GNUNET_malloc(sizeof(struct MeshPeerPath)); /* Building the path (inverted!) */ @@ -280,7 +280,7 @@ tunnel_get_path_to_peer(struct MeshTunnelTree *t, GNUNET_PEER_Id peer) * - do not disconnect peers until new path is created & connected */ int -tunnel_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, +tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, MeshNodeDisconnectCB cb) { struct MeshTunnelTreeNode *parent; @@ -302,7 +302,7 @@ tunnel_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, } if (1 == p->length) return GNUNET_OK; - oldnode = tunnel_del_path (t, p->peers[p->length - 1], cb); + oldnode = tree_del_path (t, p->peers[p->length - 1], cb); /* Look for the first node that is not already present in the tree * * Assuming that the tree is somewhat balanced, O(log n * log N). @@ -371,3 +371,55 @@ tunnel_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, } return GNUNET_OK; } + + +/** + * Destroy the node and all children + * + * @param n Parent node to be destroyed + */ +void +tree_node_destroy (struct MeshTunnelTreeNode *n) +{ + unsigned int i; + + if (n->nchildren == 0) return; + for (i = 0; i < n->nchildren; i++) + { + tree_node_destroy(&n->children[i]); + } + GNUNET_free(n->children); +} + + +/** + * Iterator over hash map peer entries and frees all data in it. + * Used prior to destroying a hashmap. Makes you miss anonymous functions in C. + * + * @param cls closure + * @param key current key code (will no longer contain valid data!!) + * @param value value in the hash map (treated as void *) + * @return GNUNET_YES if we should continue to iterate, GNUNET_NO if not. + */ +static int +iterate_free (void *cls, const GNUNET_HashCode * key, void *value) +{ + GNUNET_free(value); + return GNUNET_YES; +} + + +/** + * Destroy the whole tree and free all used memory and Peer_Ids + * + * @param t Tree to be destroyed + */ +void +tree_destroy (struct MeshTunnelTree *t) +{ + tree_node_destroy(t->root); + GNUNET_free(t->root); + GNUNET_CONTAINER_multihashmap_iterate(t->first_hops, &iterate_free, NULL); + GNUNET_CONTAINER_multihashmap_destroy(t->first_hops); + +} \ No newline at end of file diff --git a/src/mesh/mesh_tunnel_tree.h b/src/mesh/mesh_tunnel_tree.h index fddc9b46d..c7878359f 100644 --- a/src/mesh/mesh_tunnel_tree.h +++ b/src/mesh/mesh_tunnel_tree.h @@ -19,7 +19,7 @@ */ /** - * @file mesh/mesh_tunnel_tree.h + * @file mesh/mesh_tree_tree.h * @brief Tunnel tree handling functions * @author Bartlomiej Polot */ @@ -208,7 +208,7 @@ path_get_cost (struct MeshTunnelTree *t, struct MeshPeerPath *path); * @return Pointer to the node of the peer. NULL if not found. */ struct MeshTunnelTreeNode * -tunnel_find_peer (struct MeshTunnelTreeNode *root, GNUNET_PEER_Id peer_id); +tree_find_peer (struct MeshTunnelTreeNode *root, GNUNET_PEER_Id peer_id); /** @@ -218,7 +218,7 @@ tunnel_find_peer (struct MeshTunnelTreeNode *root, GNUNET_PEER_Id peer_id); * @param cb Callback to use to notify about disconnected peers */ void -tunnel_mark_peers_disconnected (struct MeshTunnelTreeNode *parent, +tree_mark_peers_disconnected (struct MeshTunnelTreeNode *parent, MeshNodeDisconnectCB cb); @@ -234,7 +234,7 @@ tunnel_mark_peers_disconnected (struct MeshTunnelTreeNode *parent, * @return pointer to the pathless node, NULL on error */ struct MeshTunnelTreeNode * -tunnel_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id, +tree_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id, MeshNodeDisconnectCB cb); @@ -249,7 +249,7 @@ tunnel_del_path (struct MeshTunnelTree *t, GNUNET_PEER_Id peer_id, * Path must be destroyed afterwards. */ struct MeshPeerPath * -tunnel_get_path_to_peer(struct MeshTunnelTree *t, GNUNET_PEER_Id peer); +tree_get_path_to_peer(struct MeshTunnelTree *t, GNUNET_PEER_Id peer); /** @@ -263,5 +263,13 @@ tunnel_get_path_to_peer(struct MeshTunnelTree *t, GNUNET_PEER_Id peer); * GNUNET_SYSERR in case of error. */ int -tunnel_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, - MeshNodeDisconnectCB cb); \ No newline at end of file +tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, + MeshNodeDisconnectCB cb); + +/** + * Destroy the whole tree and free all used memory and Peer_Ids + * + * @param t Tree to be destroyed + */ +void +tree_destroy (struct MeshTunnelTree *t); \ No newline at end of file diff --git a/src/mesh/test_mesh_path_api.c b/src/mesh/test_mesh_path_api.c index e1d62bce3..4680fda91 100644 --- a/src/mesh/test_mesh_path_api.c +++ b/src/mesh/test_mesh_path_api.c @@ -61,10 +61,7 @@ finish(void) { GNUNET_free(pi[i]); } - if (tree->root->nchildren > 0) - GNUNET_free(tree->root->children); - GNUNET_free(tree->root); - GNUNET_free(tree); + tree_destroy(tree); exit(0); } @@ -120,8 +117,8 @@ main (int argc, char *argv[]) path[0]->length = 4; finish(); - tunnel_add_path(tree, path[0], &cb); - path[1] = tunnel_get_path_to_peer(tree, 3); + tree_add_path(tree, path[0], &cb); + path[1] = tree_get_path_to_peer(tree, 3); if (path[0]->length != path[1]->length || memcmp(path[0]->peers, path[1]->peers, path[0]->length) != 0) { @@ -129,7 +126,7 @@ main (int argc, char *argv[]) failed++; } path_destroy(path[1]); - node = tunnel_find_peer(tree->root, 3); + node = tree_find_peer(tree->root, 3); if (node->peer != 3) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n"); @@ -148,7 +145,7 @@ main (int argc, char *argv[]) } return 0; - node = tunnel_find_peer(tree->root, 2); + node = tree_find_peer(tree->root, 2); if (node->peer != 2) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n"); @@ -170,7 +167,7 @@ main (int argc, char *argv[]) failed++; } - node = tunnel_find_peer(tree->root, 1); + node = tree_find_peer(tree->root, 1); if (node->peer != 1) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n"); @@ -188,9 +185,9 @@ main (int argc, char *argv[]) } path[0]->length--; - tunnel_add_path(tree, path[0], &cb); + tree_add_path(tree, path[0], &cb); - node = tunnel_find_peer(tree->root, 2); + node = tree_find_peer(tree->root, 2); if (node->peer != 2) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n"); @@ -217,7 +214,7 @@ main (int argc, char *argv[]) failed++; } - node = tunnel_find_peer(tree->root, 1); + node = tree_find_peer(tree->root, 1); if (node->peer != 1) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n"); @@ -236,9 +233,9 @@ main (int argc, char *argv[]) path[0]->length++; path[0]->peers[3] = 4; - tunnel_add_path(tree, path[0], &cb); + tree_add_path(tree, path[0], &cb); - node = tunnel_find_peer(tree->root, 2); + node = tree_find_peer(tree->root, 2); if (node->peer != 2) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n"); @@ -265,7 +262,7 @@ main (int argc, char *argv[]) failed++; } - node = tunnel_find_peer(tree->root, 1); + node = tree_find_peer(tree->root, 1); if (node->peer != 1) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n"); @@ -282,7 +279,7 @@ main (int argc, char *argv[]) failed++; } - node = tunnel_find_peer(tree->root, 4); + node = tree_find_peer(tree->root, 4); if (node->peer != 4) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n"); @@ -290,7 +287,7 @@ main (int argc, char *argv[]) } node->status = MESH_PEER_READY; cb_call = 1; - node2 = tunnel_del_path(tree, 4, &cb); + node2 = tree_del_path(tree, 4, &cb); if (cb_call != 0) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%u callbacks missed!\n", cb_call); @@ -302,7 +299,7 @@ main (int argc, char *argv[]) failed++; } // GNUNET_free(node2); FIXME destroy - node = tunnel_find_peer(tree->root, 2); + node = tree_find_peer(tree->root, 2); if (node->peer != 2) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n"); @@ -322,13 +319,13 @@ main (int argc, char *argv[]) path[0]->length = 2; path[0]->peers[1] = 3; cb_call = 1; - tunnel_add_path(tree, path[0], cb); + tree_add_path(tree, path[0], cb); if (cb_call != 0) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%u callbacks missed!\n", cb_call); failed++; } - node = tunnel_find_peer(tree->root, 2); + node = tree_find_peer(tree->root, 2); if (node->peer != 2) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n"); @@ -344,7 +341,7 @@ main (int argc, char *argv[]) GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer wrong nchildren!\n"); failed++; } - node = tunnel_find_peer(tree->root, 3); + node = tree_find_peer(tree->root, 3); if (node->peer != 3) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n"); -- 2.25.1