From bad81b517fc829ae90a65bc19f445bdee0c3d2bf Mon Sep 17 00:00:00 2001 From: Jakub Zawadzki Date: Sun, 20 Oct 2013 10:21:25 +0000 Subject: [PATCH] Reintroduce back epan_dissect_reset(), proto_tree_reset() This time it makes more sense, cause for each dissection we need two wmem allocators. Reseting wmem allocator is much faster than destroy & create. svn path=/trunk/; revision=52706 --- epan/epan.c | 35 +++++++++++++++++++++++++++++++++-- epan/epan.h | 4 ++++ epan/proto.c | 35 +++++++++++++++++++++++++++++++++-- epan/proto.h | 2 ++ 4 files changed, 72 insertions(+), 4 deletions(-) diff --git a/epan/epan.c b/epan/epan.c index 3fd514c6e5..8ad5afb9a9 100644 --- a/epan/epan.c +++ b/epan/epan.c @@ -235,6 +235,35 @@ epan_dissect_init(epan_dissect_t *edt, epan_t *session, const gboolean create_pr return edt; } +void +epan_dissect_reset(epan_dissect_t *edt) +{ + /* We have to preserve the pool pointer across the memzeroing */ + wmem_allocator_t *tmp; + + g_assert(edt); + + g_slist_free(edt->pi.dependent_frames); + + /* Free the data sources list. */ + free_data_sources(&edt->pi); + + if (edt->tvb) { + /* Free all tvb's chained from this tvb */ + tvb_free_chain(edt->tvb); + edt->tvb = NULL; + } + + if (edt->tree) + proto_tree_reset(edt->tree); + + tmp = edt->pi.pool; + wmem_free_all(tmp); + + memset(&edt->pi, 0, sizeof(edt->pi)); + edt->pi.pool = tmp; +} + epan_dissect_t* epan_dissect_new(epan_t *session, const gboolean create_proto_tree, const gboolean proto_tree_visible) { @@ -291,8 +320,10 @@ epan_dissect_cleanup(epan_dissect_t* edt) /* Free the data sources list. */ free_data_sources(&edt->pi); - /* Free all tvb's chained from this tvb */ - tvb_free_chain(edt->tvb); + if (edt->tvb) { + /* Free all tvb's chained from this tvb */ + tvb_free_chain(edt->tvb); + } if (edt->tree) { proto_tree_free(edt->tree); diff --git a/epan/epan.h b/epan/epan.h index cfa7a4d046..44f2d4c51b 100644 --- a/epan/epan.h +++ b/epan/epan.h @@ -152,6 +152,10 @@ WS_DLL_PUBLIC epan_dissect_t* epan_dissect_new(epan_t *session, const gboolean create_proto_tree, const gboolean proto_tree_visible); +WS_DLL_PUBLIC +void +epan_dissect_reset(epan_dissect_t *edt); + /** Indicate whether we should fake protocols or not */ WS_DLL_PUBLIC void diff --git a/epan/proto.c b/epan/proto.c index 0a04e9a12c..ac447bae95 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -551,6 +551,33 @@ proto_tree_free_node(proto_node *node, gpointer data _U_) FVALUE_CLEANUP(&finfo->value); } +void +proto_tree_reset(proto_tree *tree) +{ + tree_data_t *tree_data = PTREE_DATA(tree); + + proto_tree_children_foreach(tree, proto_tree_free_node, NULL); + + /* free tree data */ + if (tree_data->interesting_hfids) { + /* Free all the GPtrArray's in the interesting_hfids hash. */ + g_hash_table_foreach(tree_data->interesting_hfids, + free_GPtrArray_value, NULL); + + /* And then destroy the hash. */ + g_hash_table_destroy(tree_data->interesting_hfids); + + tree_data->interesting_hfids = NULL; + } + + /* Reset track of the number of children */ + tree_data->count = 0; + + wmem_free_all(tree_data->mem_pool); + + PROTO_NODE_INIT(tree); +} + /* frees the resources that the dissection a proto_tree uses */ void proto_tree_free(proto_tree *tree) @@ -578,6 +605,10 @@ proto_tree_free(proto_tree *tree) wmem_free_all(pool); tree_pool_cache = pool; } + + g_slice_free(tree_data_t, tree_data); + + g_slice_free(proto_tree, tree); } /* Is the parsing being done for a visible proto_tree or an invisible one? @@ -4086,11 +4117,11 @@ proto_tree_create_root(packet_info *pinfo) } /* Initialize the proto_node */ - pnode = wmem_new(pool, proto_node); + pnode = g_slice_new(proto_tree); PROTO_NODE_INIT(pnode); pnode->parent = NULL; PNODE_FINFO(pnode) = NULL; - pnode->tree_data = wmem_new(pool, tree_data_t); + pnode->tree_data = g_slice_new(tree_data_t); /* Make sure we can access pinfo everywhere */ pnode->tree_data->pinfo = pinfo; diff --git a/epan/proto.h b/epan/proto.h index 204b565278..273d74a764 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -709,6 +709,8 @@ WS_DLL_PUBLIC int proto_item_get_len(const proto_item *ti); @return the new tree root */ extern proto_tree* proto_tree_create_root(struct _packet_info *pinfo); +void proto_tree_reset(proto_tree *tree); + /** Clear memory for entry proto_tree. Clears proto_tree struct also. @param tree the tree to free */ WS_DLL_PUBLIC void proto_tree_free(proto_tree *tree);