aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis Ontanon <luis.ontanon@gmail.com>2005-03-20 00:19:15 +0000
committerLuis Ontanon <luis.ontanon@gmail.com>2005-03-20 00:19:15 +0000
commit9e9a65836965f44d9752b41ea0c9ee03ae5749fa (patch)
treee86663ae32c8fab0aa2dc50c67e9d5f8148ecff9
parent4012e774fdf10ceafe7d6925bba54c88edff545c (diff)
There was a design flaw that caused a crash on windows and
left uninitialized successive copies of the stats tree. Split the stats_tree data in two different structs one for data that's always needed and it's not going to change at every run and another for each run of the tap. svn path=/trunk/; revision=13816
-rw-r--r--epan/stats_tree.c134
-rw-r--r--epan/stats_tree_priv.h61
-rw-r--r--gtk/stats_tree_stat.c77
-rw-r--r--tap-stats_tree.c42
4 files changed, 174 insertions, 140 deletions
diff --git a/epan/stats_tree.c b/epan/stats_tree.c
index 5d08a49a58..5bc9899595 100644
--- a/epan/stats_tree.c
+++ b/epan/stats_tree.c
@@ -150,7 +150,7 @@ static void free_stat_node( stat_node* node ) {
free_stat_node(child);
}
- if(node->st->free_node_pr) node->st->free_node_pr(node);
+ if(node->st->cfg->free_node_pr) node->st->cfg->free_node_pr(node);
if (node->hash) g_hash_table_destroy(node->hash);
@@ -161,19 +161,19 @@ static void free_stat_node( stat_node* node ) {
g_free(node);
}
-/* destroys the whole tree */
+/* destroys the whole tree instance */
extern void free_stats_tree(stats_tree* st) {
stat_node* child;
- g_free(st->tapname);
- g_free(st->abbr);
g_free(st->filter);
+ g_hash_table_destroy(st->names);
+ g_ptr_array_free(st->parents,FALSE);
for (child = st->root.children; child; child = child->next )
free_stat_node(child);
- if (st->free_tree_pr)
- st->free_tree_pr(st);
+ if (st->cfg->free_tree_pr)
+ st->cfg->free_tree_pr(st);
g_free(st);
}
@@ -190,8 +190,8 @@ static void reset_stat_node(stat_node* node) {
node->counter = 0;
- if(node->st->reset_node) {
- node->st->reset_node(node);
+ if(node->st->cfg->reset_node) {
+ node->st->cfg->reset_node(node);
}
}
@@ -201,8 +201,8 @@ extern void reset_stats_tree(void* p) {
stats_tree* st = p;
reset_stat_node(&st->root);
- if (st->reset_tree) {
- st->reset_tree(st);
+ if (st->cfg->reset_tree) {
+ st->cfg->reset_tree(st);
}
}
@@ -217,8 +217,8 @@ extern void reinit_stats_tree(void* p) {
st->root.children = NULL;
st->root.counter = 0;
- if (st->init) {
- st->init(st);
+ if (st->cfg->init) {
+ st->cfg->init(st);
}
}
@@ -229,18 +229,49 @@ extern void register_stats_tree(guint8* tapname,
stat_tree_packet_cb packet,
stat_tree_init_cb init ) {
- stats_tree* st = g_malloc( sizeof(stats_tree) );
+ stats_tree_cfg* cfg = g_malloc( sizeof(stats_tree_cfg) );
/* at the very least the abbrev and the packet function should be given */
g_assert( tapname && abbr && packet );
- st->tapname = g_strdup(tapname);
- st->abbr = g_strdup(abbr);
- st->name = name ? g_strdup(name) : g_strdup(abbr);
- st->filter = NULL;
+ cfg->tapname = g_strdup(tapname);
+ cfg->abbr = g_strdup(abbr);
+ cfg->name = name ? g_strdup(name) : g_strdup(abbr);
+ cfg->packet = packet;
+ cfg->init = init;
+
+ /* these have to be filled in by implementations */
+ cfg->setup_node_pr = NULL;
+ cfg->new_tree_pr = NULL;
+ cfg->free_node_pr = NULL;
+ cfg->free_tree_pr = NULL;
+ cfg->draw_node = NULL;
+ cfg->draw_tree = NULL;
+ cfg->reset_node = NULL;
+ cfg->reset_tree = NULL;
+
+ if (!registry) registry = g_hash_table_new(g_str_hash,g_str_equal);
+
+ g_hash_table_insert(registry,cfg->abbr,cfg);
+
+}
+
+extern stats_tree* new_stats_tree(stats_tree_cfg* cfg, tree_pres* pr,char* filter) {
+ stats_tree* st = g_malloc(sizeof(stats_tree));
+
+ st->cfg = cfg;
+ st->pr = pr;
+
+ st->names = g_hash_table_new(g_str_hash,g_str_equal);
+ st->parents = g_ptr_array_new();
+ st->filter = filter;
+
+ st->start = -1.0;
+ st->elapsed = 0.0;
+
st->root.counter = 0;
- st->root.name = g_strdup(name);
+ st->root.name = g_strdup(cfg->name);
st->root.st = st;
st->root.parent = NULL;
st->root.children = NULL;
@@ -248,32 +279,10 @@ extern void register_stats_tree(guint8* tapname,
st->root.hash = NULL;
st->root.pr = NULL;
- st->names = g_hash_table_new(g_str_hash,g_str_equal);
- st->parents = g_ptr_array_new();
-
g_ptr_array_add(st->parents,&st->root);
- st->start = -1.0;
- st->elapsed = 0.0;
-
- st->packet = packet;
- st->init = init;
-
- /* these have to be filled in by implementations */
- st->setup_node_pr = NULL;
- st->new_tree_pr = NULL;
- st->free_node_pr = NULL;
- st->free_tree_pr = NULL;
- st->draw_node = NULL;
- st->draw_tree = NULL;
- st->reset_node = NULL;
- st->reset_tree = NULL;
-
- if (!registry) registry = g_hash_table_new(g_str_hash,g_str_equal);
-
- g_hash_table_insert(registry,st->abbr,st);
-
-}
+ return st;
+}
/* will be the tap packet cb */
extern int stats_tree_packet(void* p, packet_info* pinfo, epan_dissect_t *edt, const void *pri) {
@@ -285,8 +294,8 @@ extern int stats_tree_packet(void* p, packet_info* pinfo, epan_dissect_t *edt, c
st->elapsed = now - st->start;
- if (st->packet)
- return st->packet(st,pinfo,edt,pri);
+ if (st->cfg->packet)
+ return st->cfg->packet(st,pinfo,edt,pri);
else
return 0;
}
@@ -295,12 +304,12 @@ extern GHashTable* stat_tree_registry(void) {
return registry;
}
-extern stats_tree* get_stats_tree_by_abbr(guint8* abbr) {
+extern stats_tree_cfg* get_stats_tree_by_abbr(guint8* abbr) {
return g_hash_table_lookup(registry,abbr);
}
-struct _stats_tree_pres_stuff {
+struct _stats_tree_pres_cbs {
void (*setup_node_pr)(stat_node*);
void (*free_node_pr)(stat_node*);
void (*draw_node)(stat_node*);
@@ -312,17 +321,17 @@ struct _stats_tree_pres_stuff {
};
static void setup_tree_presentation(gpointer k _U_, gpointer v, gpointer p) {
- stats_tree* st = v;
- struct _stats_tree_pres_stuff *d = p;
-
- st->setup_node_pr = d->setup_node_pr;
- st->new_tree_pr = d->new_tree_pr;
- st->free_node_pr = d->free_node_pr;
- st->free_tree_pr = d->free_tree_pr;
- st->draw_node = d->draw_node;
- st->draw_tree = d->draw_tree;
- st->reset_node = d->reset_node;
- st->reset_tree = d->reset_tree;
+ stats_tree_cfg* cfg = v;
+ struct _stats_tree_pres_cbs *d = p;
+
+ cfg->setup_node_pr = d->setup_node_pr;
+ cfg->new_tree_pr = d->new_tree_pr;
+ cfg->free_node_pr = d->free_node_pr;
+ cfg->free_tree_pr = d->free_tree_pr;
+ cfg->draw_node = d->draw_node;
+ cfg->draw_tree = d->draw_tree;
+ cfg->reset_node = d->reset_node;
+ cfg->reset_tree = d->reset_tree;
}
@@ -336,7 +345,7 @@ extern void stats_tree_presentation(void (*registry_iterator)(gpointer,gpointer,
void (*draw_tree)(stats_tree*),
void (*reset_tree)(stats_tree*),
void* data) {
- struct _stats_tree_pres_stuff d = {setup_node_pr,free_node_pr,draw_node,reset_node,new_tree_pr,free_tree_pr,draw_tree,reset_tree};
+ struct _stats_tree_pres_cbs d = {setup_node_pr,free_node_pr,draw_node,reset_node,new_tree_pr,free_tree_pr,draw_tree,reset_tree};
if (registry) g_hash_table_foreach(registry,setup_tree_presentation,&d);
@@ -407,15 +416,15 @@ static stat_node* new_stat_node(stats_tree* st,
g_hash_table_insert(node->parent->hash,node->name,node);
}
- if (st->setup_node_pr) {
- st->setup_node_pr(node);
+ if (st->cfg->setup_node_pr) {
+ st->cfg->setup_node_pr(node);
} else {
node->pr = NULL;
}
return node;
}
-
+/***/
extern int create_node(stats_tree* st, const gchar* name, int parent_id, gboolean with_hash) {
stat_node* node = new_stat_node(st,name,parent_id,with_hash,TRUE);
@@ -527,13 +536,14 @@ extern int create_range_node(stats_tree* st,
return rng_root->id;
}
+/****/
extern int get_parent_id_by_name(stats_tree* st, const gchar* parent_name) {
stat_node* node = g_hash_table_lookup(st->names,parent_name);
if (node)
return node->id;
else
- return 0; /* ??? -1 ??? */
+ return 0; /* XXX: this is the root shoud we return -1 instead?*/
}
diff --git a/epan/stats_tree_priv.h b/epan/stats_tree_priv.h
index 950c4bc1f5..078d343a60 100644
--- a/epan/stats_tree_priv.h
+++ b/epan/stats_tree_priv.h
@@ -35,13 +35,18 @@
* as well as some operations on it */
typedef struct _st_node_pres st_node_pres;
-/* implementations should define this to contain its own tree related data
+/* implementations should define this to contain its own dynamic tree related data
* as well as some operations on it */
typedef struct _tree_pres tree_pres;
-typedef struct _stat_node stat_node;
+/* implementations should define this to contain its own static tree related data
+* as well as some operations on it */
+typedef struct _tree_cfg_pres tree_cfg_pres;
+typedef struct _stat_node stat_node;
+typedef struct _stats_tree_cfg stats_tree_cfg;
+
typedef struct _range_pair {
gint floor;
gint ceil;
@@ -58,7 +63,7 @@ struct _stat_node {
GHashTable* hash;
/* the owner of this node */
- stats_tree* st;
+ stats_tree* st;
/* relatives */
stat_node* parent;
@@ -70,44 +75,52 @@ struct _stat_node {
/* node presentation data */
st_node_pres* pr;
-} ;
+};
struct _stats_tree {
- guint8* abbr;
- guint8* name;
- guint8* tapname;
+ /* the "class" from which it's derived */
+ stats_tree_cfg* cfg;
char* filter;
/* times */
float start;
float elapsed;
-
- /* used to lookup named parents:
- * key: parent node name
- * value: parent node
- */
+ /* used to lookup named parents:
+ * key: parent node name
+ * value: parent node
+ */
GHashTable* names;
- /* used for quicker lookups of parent nodes */
+ /* used for quicker lookups of parent nodes */
GPtrArray* parents;
+
+ /*
+ * tree representation
+ * to be defined (if needed) by the implementations
+ */
+ tree_pres* pr;
/* every tree in nature has one */
stat_node root;
+};
+
+struct _stats_tree_cfg {
+ guint8* abbr;
+ guint8* name;
+ guint8* tapname;
+
/* dissector defined callbacks */
stat_tree_packet_cb packet;
stat_tree_init_cb init;
- /**** tree representation
- * to be defined (if needed) by the implementations
- */
- tree_pres* pr;
- /* node presentation callbacks
+ /*
+ * node presentation callbacks
*/
-
+
/* last to be called at node creation */
void (*setup_node_pr)(stat_node*);
@@ -118,7 +131,11 @@ struct _stats_tree {
void (*draw_node)(stat_node*);
void (*reset_node)(stat_node*);
- /* tree presentation callbacks */
+ /*
+ * tree presentation callbacks
+ */
+ tree_cfg_pres* pr;
+
tree_pres* (*new_tree_pr)(stats_tree*);
void (*free_tree_pr)(stats_tree*);
@@ -138,6 +155,8 @@ extern void stats_tree_presentation(void (*registry_iterator)(gpointer,gpointer,
void (*reset_tree)(stats_tree*),
void* data);
+extern stats_tree* new_stats_tree(stats_tree_cfg* cfg, tree_pres* pr, char* filter);
+
/* callback for taps */
extern int stats_tree_packet(void*, packet_info*, epan_dissect_t*, const void *);
@@ -155,7 +174,7 @@ extern void free_stats_tree(stats_tree* st);
extern guint8* get_st_abbr(const guint8* optarg);
/* obtains a stats tree from the registry given its abbr */
-extern stats_tree* get_stats_tree_by_abbr(guint8* abbr);
+extern stats_tree_cfg* get_stats_tree_by_abbr(guint8* abbr);
/* extracts node data as strings from a stat_node into
the buffers given by value, rate and precent
diff --git a/gtk/stats_tree_stat.c b/gtk/stats_tree_stat.c
index 2cf0dbf955..968b48395d 100644
--- a/gtk/stats_tree_stat.c
+++ b/gtk/stats_tree_stat.c
@@ -57,9 +57,11 @@ struct _st_node_pres {
#endif
};
+struct _tree_cfg_pres {
+ tap_dfilter_dlg* stat_dlg;
+};
struct _tree_pres {
- tap_dfilter_dlg* stat_dlg;
GString* text;
GtkWidget* win;
@@ -187,6 +189,9 @@ static void free_gtk_tree(GtkWindow *win _U_, stats_tree *st)
if (st->root.pr)
st->root.pr->iter = NULL;
#endif
+
+ free_stats_tree(st);
+
}
@@ -194,6 +199,8 @@ static void free_gtk_tree(GtkWindow *win _U_, stats_tree *st)
static void init_gtk_tree(char* optarg) {
guint8* abbr = get_st_abbr(optarg);
stats_tree* st = NULL;
+ stats_tree_cfg* cfg = NULL;
+ tree_pres* pr = g_malloc(sizeof(tree_pres));
guint8* title = NULL;
guint8* window_name = NULL;
GString* error_string;
@@ -206,20 +213,20 @@ static void init_gtk_tree(char* optarg) {
#endif
if (abbr) {
- st = get_stats_tree_by_abbr(abbr);
+ cfg = get_stats_tree_by_abbr(abbr);
- if (st != NULL) {
- init_strlen = strlen(st->pr->stat_dlg->init_string);
+ if (cfg != NULL) {
+ init_strlen = strlen(cfg->pr->stat_dlg->init_string);
- if (strncmp (optarg, st->pr->stat_dlg->init_string, init_strlen) == 0){
+ if (strncmp (optarg, cfg->pr->stat_dlg->init_string, init_strlen) == 0){
if (init_strlen == strlen(optarg)) {
- st->filter= "";
+ st = new_stats_tree(cfg,pr,NULL);
} else {
- st->filter=((guint8*)optarg)+init_strlen+1;
+ st = new_stats_tree(cfg,pr,((guint8*)optarg)+init_strlen+1);
}
} else {
- st->filter=NULL;
+ st = new_stats_tree(cfg,pr,NULL);
}
} else {
g_error("no such stats_tree (%s) found in stats_tree registry",abbr);
@@ -229,18 +236,18 @@ static void init_gtk_tree(char* optarg) {
} else {
g_error("could not obtain stats_tree abbr from optarg");
}
-
- window_name = g_strdup_printf("%s Stats Tree", st->name);
+
+ window_name = g_strdup_printf("%s Stats Tree", cfg->name);
st->pr->win = window_new_with_geom(GTK_WINDOW_TOPLEVEL,window_name,window_name);
gtk_window_set_default_size(GTK_WINDOW(st->pr->win), 400, 400);
g_free(window_name);
if(st->filter){
- title=g_strdup_printf("%s with filter: %s",st->name,st->filter);
+ title=g_strdup_printf("%s with filter: %s",cfg->name,st->filter);
} else {
st->filter=NULL;
- title=g_strdup_printf("%s", st->name);
+ title=g_strdup_printf("%s", cfg->name);
}
gtk_window_set_title(GTK_WINDOW(st->pr->win), title);
@@ -302,7 +309,7 @@ static void init_gtk_tree(char* optarg) {
gtk_container_add( GTK_CONTAINER(main_vb), scr_win);
#endif
- error_string = register_tap_listener( st->tapname,
+ error_string = register_tap_listener( cfg->tapname,
st,
st->filter,
NULL,
@@ -313,7 +320,7 @@ static void init_gtk_tree(char* optarg) {
/* error, we failed to attach to the tap. clean up */
simple_dialog( ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str );
/* destroy_stat_tree_window(st); */
- g_error("stats_tree for: %s failed to attach to the tap: %s",st->name,error_string->str);
+ g_error("stats_tree for: %s failed to attach to the tap: %s",cfg->name,error_string->str);
g_string_free(error_string, TRUE);
}
@@ -334,45 +341,35 @@ static void init_gtk_tree(char* optarg) {
gtk_tree_view_set_model(GTK_TREE_VIEW(st->pr->tree),GTK_TREE_MODEL(st->pr->store));
#endif
- if (st->filter) {
- reinit_stats_tree(st);
- } else {
- st->init(st);
- }
+ st->cfg->init(st);
cf_retap_packets(&cfile);
-
}
static void register_gtk_stats_tree_tap (gpointer k _U_, gpointer v, gpointer p _U_) {
- stats_tree* st = v;
+ stats_tree_cfg* cfg = v;
guint8* s;
- s = g_strdup_printf("%s,tree",st->abbr);
+ s = g_strdup_printf("%s,tree",cfg->abbr);
register_ethereal_tap(s, init_gtk_tree);
- st->pr = g_malloc(sizeof(tree_pres));
- st->pr->text = NULL;
- st->pr->win = NULL;
-
-#if GTK_MAJOR_VERSION >= 2
- st->pr->store = NULL;
- st->pr->tree = NULL;
-#else
- st->pr->textbox = NULL;
-#endif
+ cfg->pr = g_malloc(sizeof(tree_pres));
- st->pr->stat_dlg = g_malloc(sizeof(tap_dfilter_dlg));
+ cfg->pr->stat_dlg = g_malloc(sizeof(tap_dfilter_dlg));
- st->pr->stat_dlg->win_title = g_strdup_printf("%s Stats Tree",st->name);
- st->pr->stat_dlg->init_string = g_strdup_printf("%s,tree",st->abbr);
- st->pr->stat_dlg->tap_init_cb = init_gtk_tree;
- st->pr->stat_dlg->index = -1;
+ cfg->pr->stat_dlg->win_title = g_strdup_printf("%s Stats Tree",cfg->name);
+ cfg->pr->stat_dlg->init_string = g_strdup_printf("%s,tree",cfg->abbr);
+ cfg->pr->stat_dlg->tap_init_cb = init_gtk_tree;
+ cfg->pr->stat_dlg->index = -1;
- register_tap_menu_item(st->name, REGISTER_TAP_GROUP_NONE,
- gtk_tap_dfilter_dlg_cb, NULL, NULL, st->pr->stat_dlg);
+ register_tap_menu_item(cfg->name, REGISTER_TAP_GROUP_NONE,
+ gtk_tap_dfilter_dlg_cb, NULL, NULL, cfg->pr->stat_dlg);
+}
+
+static void free_tree_presentation(stats_tree* st) {
+ g_free(st->pr);
}
void
@@ -382,5 +379,5 @@ register_tap_listener_stats_tree_stat(void)
stats_tree_presentation(register_gtk_stats_tree_tap,
setup_gtk_node_pr, NULL,
NULL,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, free_tree_presentation, NULL, NULL, NULL);
}
diff --git a/tap-stats_tree.c b/tap-stats_tree.c
index 2c85abcd92..4c0f3a1925 100644
--- a/tap-stats_tree.c
+++ b/tap-stats_tree.c
@@ -37,8 +37,11 @@ struct _st_node_pres {
void* dummy;
};
-
struct _tree_pres {
+ void* dummy;
+};
+
+struct _tree_cfg_pres {
guint8* init_string;
};
@@ -50,7 +53,7 @@ static void draw_stats_tree(void *psp) {
s = g_string_new("\n===================================================================\n");
fmt = g_strdup_printf(" %%s%%-%us%%12s\t%%12s\t%%12s\n",stats_branch_max_name_len(&st->root,0));
- g_string_sprintfa(s,fmt,"",st->name,"value","rate","percent");
+ g_string_sprintfa(s,fmt,"",st->cfg->name,"value","rate","percent");
g_free(fmt);
g_string_sprintfa(s,"-------------------------------------------------------------------\n");
@@ -67,14 +70,15 @@ static void draw_stats_tree(void *psp) {
static void init_stats_tree(char *optarg) {
guint8* abbr = get_st_abbr(optarg);
GString *error_string;
- stats_tree *st = NULL;
-
+ stats_tree_cfg *cfg = NULL;
+ stats_tree* st = NULL;
+
if (abbr) {
- st = get_stats_tree_by_abbr(abbr);
-
- if (st != NULL) {
- if (strncmp (optarg, st->pr->init_string, strlen(st->pr->init_string)) == 0){
- st->filter=((guint8*)optarg)+strlen(st->pr->init_string);
+ cfg = get_stats_tree_by_abbr(abbr);
+
+ if (cfg != NULL) {
+ if (strncmp (optarg, cfg->pr->init_string, strlen(cfg->pr->init_string)) == 0){
+ st = new_stats_tree(cfg,NULL,((guint8*)optarg)+strlen(cfg->pr->init_string));
} else {
st->filter=NULL;
}
@@ -88,7 +92,7 @@ static void init_stats_tree(char *optarg) {
g_error("could not obtain stats_tree abbr (%s) from optarg '%s'",abbr,optarg);
}
- error_string = register_tap_listener( st->tapname,
+ error_string = register_tap_listener( st->cfg->tapname,
st,
st->filter,
reset_stats_tree,
@@ -96,28 +100,32 @@ static void init_stats_tree(char *optarg) {
draw_stats_tree);
if (error_string) {
- g_error("stats_tree for: %s failed to attach to the tap: %s",st->name,error_string->str);
+ g_error("stats_tree for: %s failed to attach to the tap: %s",cfg->name,error_string->str);
}
- if (st->init) st->init(st);
+ if (cfg->init) cfg->init(st);
}
void register_stats_tree_tap (gpointer k _U_, gpointer v, gpointer p _U_) {
- stats_tree* st = v;
+ stats_tree_cfg* cfg = v;
- st->pr = g_malloc(sizeof(tree_pres));
- st->pr->init_string = g_strdup_printf("%s,tree",st->abbr);
+ cfg->pr = g_malloc(sizeof(tree_cfg_pres));
+ cfg->pr->init_string = g_strdup_printf("%s,tree",cfg->abbr);
- register_ethereal_tap(st->pr->init_string, init_stats_tree);
+ register_ethereal_tap(cfg->pr->init_string, init_stats_tree);
}
+static void free_tree_presentation(stats_tree* st) {
+ g_free(st->pr);
+}
+
void
register_tap_listener_stats_tree_stat(void)
{
stats_tree_presentation(register_stats_tree_tap,
NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL);
+ free_tree_presentation, NULL, NULL, NULL);
}