diff options
author | Michael Mann <mmann78@netscape.net> | 2017-02-09 12:28:14 -0500 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2017-02-10 13:26:14 +0000 |
commit | b54c43801112711dcba341f3eb4701678a0e1916 (patch) | |
tree | 49c8f27b4ad96bd35189451addd1ab6941a408a3 | |
parent | 8bbf0341e13b28f76a2e0d9c31bc0912aba36327 (diff) | |
download | wireshark-b54c43801112711dcba341f3eb4701678a0e1916.tar.gz |
Convert conversation hash tables to use wmem.
Simplifies cleanup because wmem can handle the memory cleanup.
Change-Id: Idc6a9bfe5f23c83b59a5278a64b9fb706862342d
Reviewed-on: https://code.wireshark.org/review/20042
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
-rw-r--r-- | epan/conversation.c | 114 | ||||
-rw-r--r-- | epan/conversation.h | 15 | ||||
-rw-r--r-- | epan/epan.c | 9 | ||||
-rw-r--r-- | epan/epan.h | 1 | ||||
-rw-r--r-- | epan/packet.c | 5 | ||||
-rw-r--r-- | ui/gtk/conversation_hastables_dlg.c | 18 | ||||
-rw-r--r-- | ui/qt/conversation_hash_tables_dialog.cpp | 49 | ||||
-rw-r--r-- | ui/qt/conversation_hash_tables_dialog.h | 3 |
8 files changed, 86 insertions, 128 deletions
diff --git a/epan/conversation.c b/epan/conversation.c index 1760270fa5..5d32c11721 100644 --- a/epan/conversation.c +++ b/epan/conversation.c @@ -39,39 +39,23 @@ int _debug_conversation_indent = 0; /* * Hash table for conversations with no wildcards. */ -static GHashTable *conversation_hashtable_exact = NULL; +static wmem_map_t *conversation_hashtable_exact = NULL; /* * Hash table for conversations with one wildcard address. */ -static GHashTable *conversation_hashtable_no_addr2 = NULL; +static wmem_map_t *conversation_hashtable_no_addr2 = NULL; /* * Hash table for conversations with one wildcard port. */ -static GHashTable *conversation_hashtable_no_port2 = NULL; +static wmem_map_t *conversation_hashtable_no_port2 = NULL; /* * Hash table for conversations with one wildcard address and port. */ -static GHashTable *conversation_hashtable_no_addr2_or_port2 = NULL; - - -#ifdef __NOT_USED__ -typedef struct conversation_key { - struct conversation_key *next; - address addr1; - address addr2; - port_type ptype; - guint32 port1; - guint32 port2; -} conversation_key; -#endif -/* - * Linked list of conversation keys, so we can, before freeing them all, - * free the address data allocations associated with them. - */ -static conversation_key *conversation_keys; +static wmem_map_t *conversation_hashtable_no_addr2_or_port2 = NULL; + static guint32 new_index; @@ -446,40 +430,8 @@ conversation_match_no_addr2_or_port2(gconstpointer v, gconstpointer w) return 0; } -/* - * Destroy all existing conversations - */ -void -conversation_cleanup(void) -{ - /* Clean up the hash tables, but only after freeing any proto_data - * that may be hanging off the conversations. - * The conversation keys are wmem-allocated with file scope so we - * don't have to clean them up. - */ - conversation_keys = NULL; - if (conversation_hashtable_exact != NULL) { - g_hash_table_destroy(conversation_hashtable_exact); - } - if (conversation_hashtable_no_addr2 != NULL) { - g_hash_table_destroy(conversation_hashtable_no_addr2); - } - if (conversation_hashtable_no_port2 != NULL) { - g_hash_table_destroy(conversation_hashtable_no_port2); - } - if (conversation_hashtable_no_addr2_or_port2 != NULL) { - g_hash_table_destroy(conversation_hashtable_no_addr2_or_port2); - } - - conversation_hashtable_exact = NULL; - conversation_hashtable_no_addr2 = NULL; - conversation_hashtable_no_port2 = NULL; - conversation_hashtable_no_addr2_or_port2 = NULL; -} - -/* - * Initialize some variables every time a file is loaded or re-loaded. - * Create a new hash table for the conversations in the new file. +/** + * Create a new hash tables for conversations. */ void conversation_init(void) @@ -493,18 +445,25 @@ conversation_init(void) * above. */ conversation_hashtable_exact = - g_hash_table_new(conversation_hash_exact, + wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), conversation_hash_exact, conversation_match_exact); conversation_hashtable_no_addr2 = - g_hash_table_new(conversation_hash_no_addr2, + wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), conversation_hash_no_addr2, conversation_match_no_addr2); conversation_hashtable_no_port2 = - g_hash_table_new(conversation_hash_no_port2, + wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), conversation_hash_no_port2, conversation_match_no_port2); conversation_hashtable_no_addr2_or_port2 = - g_hash_table_new(conversation_hash_no_addr2_or_port2, + wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), conversation_hash_no_addr2_or_port2, conversation_match_no_addr2_or_port2); +} + +/** + * Initialize some variables every time a file is loaded or re-loaded. + */ +void conversation_epan_reset(void) +{ /* * Start the conversation indices over at 0. */ @@ -518,17 +477,17 @@ conversation_init(void) * Mostly adapted from the old conversation_new(). */ static void -conversation_insert_into_hashtable(GHashTable *hashtable, conversation_t *conv) +conversation_insert_into_hashtable(wmem_map_t *hashtable, conversation_t *conv) { conversation_t *chain_head, *chain_tail, *cur, *prev; - chain_head = (conversation_t *)g_hash_table_lookup(hashtable, conv->key_ptr); + chain_head = (conversation_t *)wmem_map_lookup(hashtable, conv->key_ptr); if (NULL==chain_head) { /* New entry */ conv->next = NULL; conv->last = conv; - g_hash_table_insert(hashtable, conv->key_ptr, conv); + wmem_map_insert(hashtable, conv->key_ptr, conv); DPRINT(("created a new conversation chain")); } else { @@ -557,7 +516,7 @@ conversation_insert_into_hashtable(GHashTable *hashtable, conversation_t *conv) conv->next = chain_head; conv->last = chain_tail; chain_head->last = NULL; - g_hash_table_insert(hashtable, conv->key_ptr, conv); + wmem_map_insert(hashtable, conv->key_ptr, conv); } else { /* Inserting into the middle of the chain */ @@ -574,21 +533,20 @@ conversation_insert_into_hashtable(GHashTable *hashtable, conversation_t *conv) * taking into account ordering and hash chains and all that good stuff. */ static void -conversation_remove_from_hashtable(GHashTable *hashtable, conversation_t *conv) +conversation_remove_from_hashtable(wmem_map_t *hashtable, conversation_t *conv) { conversation_t *chain_head, *cur, *prev; - chain_head = (conversation_t *)g_hash_table_lookup(hashtable, conv->key_ptr); + chain_head = (conversation_t *)wmem_map_lookup(hashtable, conv->key_ptr); if (conv == chain_head) { /* We are currently the front of the chain */ if (NULL == conv->next) { /* We are the only conversation in the chain, no need to * update next pointer, but do not call - * g_hash_table_remove() either because the conv data - * will be re-inserted. The memory is released when - * conversion_cleanup() is called. */ - g_hash_table_steal(hashtable, conv->key_ptr); + * wmem_map_remove() either because the conv data + * will be re-inserted. */ + wmem_map_steal(hashtable, conv->key_ptr); } else { /* Update the head of the chain */ @@ -600,7 +558,7 @@ conversation_remove_from_hashtable(GHashTable *hashtable, conversation_t *conv) else chain_head->latest_found = conv->latest_found; - g_hash_table_insert(hashtable, chain_head->key_ptr, chain_head); + wmem_map_insert(hashtable, chain_head->key_ptr, chain_head); } } else { @@ -646,7 +604,7 @@ conversation_new(const guint32 setup_frame, const address *addr1, const address DISSECTOR_ASSERT(!(options | CONVERSATION_TEMPLATE) || ((options | (NO_ADDR2 | NO_PORT2 | NO_PORT2_FORCE))) && "A conversation template may not be constructed without wildcard options"); */ - GHashTable* hashtable; + wmem_map_t* hashtable; conversation_t *conversation=NULL; conversation_key *new_key; @@ -669,8 +627,6 @@ conversation_new(const guint32 setup_frame, const address *addr1, const address } new_key = wmem_new(wmem_file_scope(), struct conversation_key); - new_key->next = conversation_keys; - conversation_keys = new_key; copy_address_wmem(wmem_file_scope(), &new_key->addr1, addr1); copy_address_wmem(wmem_file_scope(), &new_key->addr2, addr2); new_key->ptype = ptype; @@ -775,7 +731,7 @@ conversation_set_addr2(conversation_t *conv, const address *addr) * {addr1, port1, addr2, port2} and set up before frame_num. */ static conversation_t * -conversation_lookup_hashtable(GHashTable *hashtable, const guint32 frame_num, const address *addr1, const address *addr2, +conversation_lookup_hashtable(wmem_map_t *hashtable, const guint32 frame_num, const address *addr1, const address *addr2, const port_type ptype, const guint32 port1, const guint32 port2) { conversation_t* convo=NULL; @@ -793,7 +749,7 @@ conversation_lookup_hashtable(GHashTable *hashtable, const guint32 frame_num, co key.port1 = port1; key.port2 = port2; - chain_head = (conversation_t *)g_hash_table_lookup(hashtable, &key); + chain_head = (conversation_t *)wmem_map_lookup(hashtable, &key); if (chain_head && (chain_head->setup_frame <= frame_num)) { match = chain_head; @@ -1316,25 +1272,25 @@ find_or_create_conversation(packet_info *pinfo) return conv; } -GHashTable * +wmem_map_t * get_conversation_hashtable_exact(void) { return conversation_hashtable_exact; } -GHashTable * +wmem_map_t * get_conversation_hashtable_no_addr2(void) { return conversation_hashtable_no_addr2; } -GHashTable * +wmem_map_t * get_conversation_hashtable_no_port2(void) { return conversation_hashtable_no_port2; } -GHashTable * +wmem_map_t * get_conversation_hashtable_no_addr2_or_port2(void) { return conversation_hashtable_no_addr2_or_port2; diff --git a/epan/conversation.h b/epan/conversation.h index 7b1c0a6b81..d31a210200 100644 --- a/epan/conversation.h +++ b/epan/conversation.h @@ -86,15 +86,14 @@ typedef struct conversation { } conversation_t; /** - * Destroy all existing conversations + * Create a new hash tables for conversations. */ -extern void conversation_cleanup(void); +extern void conversation_init(void); /** * Initialize some variables every time a file is loaded or re-loaded. - * Create a new hash table for the conversations in the new file. */ -extern void conversation_init(void); +extern void conversation_epan_reset(void); /* * Given two address/port pairs for a packet, create a new conversation @@ -189,16 +188,16 @@ extern void conversation_set_port2(conversation_t *conv, const guint32 port); extern void conversation_set_addr2(conversation_t *conv, const address *addr); WS_DLL_PUBLIC -GHashTable *get_conversation_hashtable_exact(void); +wmem_map_t *get_conversation_hashtable_exact(void); WS_DLL_PUBLIC -GHashTable *get_conversation_hashtable_no_addr2(void); +wmem_map_t *get_conversation_hashtable_no_addr2(void); WS_DLL_PUBLIC -GHashTable * get_conversation_hashtable_no_port2(void); +wmem_map_t * get_conversation_hashtable_no_port2(void); WS_DLL_PUBLIC -GHashTable *get_conversation_hashtable_no_addr2_or_port2(void); +wmem_map_t *get_conversation_hashtable_no_addr2_or_port2(void); #ifdef __cplusplus diff --git a/epan/epan.c b/epan/epan.c index e0ebd5b215..ffb4bddecf 100644 --- a/epan/epan.c +++ b/epan/epan.c @@ -172,6 +172,7 @@ epan_init(void (*register_all_protocols_func)(register_cb cb, gpointer client_da prefs_init(); expert_init(); packet_init(); + conversation_init(); capture_dissector_init(); reassembly_tables_init(); proto_init(register_all_protocols_func, register_all_handoffs_func, @@ -308,13 +309,7 @@ epan_free(epan_t *session) void epan_conversation_init(void) { - conversation_init(); -} - -void -epan_conversation_cleanup(void) -{ - conversation_cleanup(); + conversation_epan_reset(); } void diff --git a/epan/epan.h b/epan/epan.h index 3a1e742d14..f809c117f9 100644 --- a/epan/epan.h +++ b/epan/epan.h @@ -113,7 +113,6 @@ void epan_cleanup(void); * value indicating to which flow the packet belongs. */ void epan_conversation_init(void); -void epan_conversation_cleanup(void); /** * Initialize the table of circuits. Circuits are identified by a diff --git a/epan/packet.c b/epan/packet.c index b8bd6a38e8..de0a84854a 100644 --- a/epan/packet.c +++ b/epan/packet.c @@ -320,11 +320,6 @@ init_dissection(void) void cleanup_dissection(void) { - /* Cleanup the table of conversations. Do this before freeing seasonal - * memory (at least until conversation's use of g_slist is changed). - */ - epan_conversation_cleanup(); - /* Cleanup the table of circuits. */ epan_circuit_cleanup(); diff --git a/ui/gtk/conversation_hastables_dlg.c b/ui/gtk/conversation_hastables_dlg.c index 1e2df8cfc8..04f8f581dc 100644 --- a/ui/gtk/conversation_hastables_dlg.c +++ b/ui/gtk/conversation_hastables_dlg.c @@ -132,10 +132,10 @@ static void conversation_info_to_texbuff(GtkTextBuffer *buffer) { gchar string_buff[CONV_STR_BUF_MAX]; - GHashTable *conversation_hashtable_exact; - GHashTable *conversation_hashtable_no_addr2; - GHashTable *conversation_hashtable_no_port2; - GHashTable *conversation_hashtable_no_addr2_or_port2; + wmem_map_t *conversation_hashtable_exact; + wmem_map_t *conversation_hashtable_no_addr2; + wmem_map_t *conversation_hashtable_no_port2; + wmem_map_t *conversation_hashtable_no_addr2_or_port2; g_snprintf(string_buff, CONV_STR_BUF_MAX, "Conversation hastables info:\n"); gtk_text_buffer_insert_at_cursor (buffer, string_buff, -1); @@ -143,15 +143,15 @@ conversation_info_to_texbuff(GtkTextBuffer *buffer) conversation_hashtable_exact = get_conversation_hashtable_exact(); if(conversation_hashtable_exact){ g_snprintf(string_buff, CONV_STR_BUF_MAX, "conversation_hashtable_exact %i entries\n#\n", - g_hash_table_size(conversation_hashtable_exact)); + wmem_map_size(conversation_hashtable_exact)); gtk_text_buffer_insert_at_cursor (buffer, string_buff, -1); - g_hash_table_foreach( conversation_hashtable_exact, conversation_hashtable_exact_to_texbuff, buffer); + wmem_map_foreach( conversation_hashtable_exact, conversation_hashtable_exact_to_texbuff, buffer); } conversation_hashtable_no_addr2 = get_conversation_hashtable_no_addr2(); if(conversation_hashtable_no_addr2){ g_snprintf(string_buff, CONV_STR_BUF_MAX, "conversation_hashtable_no_addr2 %i entries\n#\n", - g_hash_table_size(conversation_hashtable_no_addr2)); + wmem_map_size(conversation_hashtable_no_addr2)); gtk_text_buffer_insert_at_cursor (buffer, string_buff, -1); } @@ -159,7 +159,7 @@ conversation_info_to_texbuff(GtkTextBuffer *buffer) conversation_hashtable_no_port2 = get_conversation_hashtable_no_port2(); if(conversation_hashtable_no_port2){ g_snprintf(string_buff, CONV_STR_BUF_MAX, "conversation_hashtable_no_port2 %i entries\n#\n", - g_hash_table_size(conversation_hashtable_no_port2)); + wmem_map_size(conversation_hashtable_no_port2)); gtk_text_buffer_insert_at_cursor (buffer, string_buff, -1); } @@ -167,7 +167,7 @@ conversation_info_to_texbuff(GtkTextBuffer *buffer) conversation_hashtable_no_addr2_or_port2 = get_conversation_hashtable_no_addr2_or_port2(); if(conversation_hashtable_no_addr2_or_port2){ g_snprintf(string_buff, CONV_STR_BUF_MAX, "conversation_hashtable_no_addr2_or_port2 %i entries\n#\n", - g_hash_table_size(conversation_hashtable_no_addr2_or_port2)); + wmem_map_size(conversation_hashtable_no_addr2_or_port2)); gtk_text_buffer_insert_at_cursor (buffer, string_buff, -1); } diff --git a/ui/qt/conversation_hash_tables_dialog.cpp b/ui/qt/conversation_hash_tables_dialog.cpp index 713d711bc5..a0f2566da5 100644 --- a/ui/qt/conversation_hash_tables_dialog.cpp +++ b/ui/qt/conversation_hash_tables_dialog.cpp @@ -58,30 +58,43 @@ ConversationHashTablesDialog::~ConversationHashTablesDialog() delete ui; } -const QString ConversationHashTablesDialog::hashTableToHtmlTable(const QString table_name, struct _GHashTable *hash_table) +static void +populate_html_table(gpointer data, gpointer user_data) { - GList *conversation_keys = NULL; - if (hash_table) conversation_keys = g_hash_table_get_keys(hash_table); - int num_keys = g_list_length(conversation_keys); + const conversation_key *conv_key = (const conversation_key *)data; + QString* html_table = (QString*)user_data; - QString html_table = QString("<p>%1, %2 entries</p>").arg(table_name).arg(num_keys); - if (num_keys < 1) return html_table; + // XXX Add a column for the hash value. + (*html_table) += QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td></tr>\n") + .arg(address_to_qstring(&conv_key->addr1)) + .arg(conv_key->port1) + .arg(address_to_qstring(&conv_key->addr2)) + .arg(conv_key->port2); +} + +const QString ConversationHashTablesDialog::hashTableToHtmlTable(const QString table_name, wmem_map_t *hash_table) +{ + wmem_list_t *conversation_keys = NULL; + guint num_keys = 0; + if (hash_table) + { + conversation_keys = wmem_map_get_keys(NULL, hash_table); + num_keys = wmem_list_count(conversation_keys); + } - int one_em = fontMetrics().height(); - html_table += QString("<table cellpadding=\"%1\">\n").arg(one_em / 4); + QString html_table = QString("<p>%1, %2 entries</p>").arg(table_name).arg(num_keys); + if (num_keys > 0) + { + int one_em = fontMetrics().height(); + html_table += QString("<table cellpadding=\"%1\">\n").arg(one_em / 4); - html_table += "<tr><th align=\"left\">Address 1</th><th align=\"left\">Port 1</th><th align=\"left\">Address 2</th><th align=\"left\">Port 2</th></tr>\n"; + html_table += "<tr><th align=\"left\">Address 1</th><th align=\"left\">Port 1</th><th align=\"left\">Address 2</th><th align=\"left\">Port 2</th></tr>\n"; - // XXX Add a column for the hash value. - for (GList *ck_entry = conversation_keys; ck_entry; ck_entry = g_list_next(ck_entry)) { - const conversation_key *conv_key = (conversation_key *) ck_entry->data; - html_table += QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td></tr>\n") - .arg(address_to_qstring(&conv_key->addr1)) - .arg(conv_key->port1) - .arg(address_to_qstring(&conv_key->addr2)) - .arg(conv_key->port2); + wmem_list_foreach(conversation_keys, populate_html_table, (void*)&html_table); + html_table += "</table>\n"; } - html_table += "</table>\n"; + if (conversation_keys) + wmem_destroy_list(conversation_keys); return html_table; } diff --git a/ui/qt/conversation_hash_tables_dialog.h b/ui/qt/conversation_hash_tables_dialog.h index a0299c428d..4b0d35fa77 100644 --- a/ui/qt/conversation_hash_tables_dialog.h +++ b/ui/qt/conversation_hash_tables_dialog.h @@ -23,6 +23,7 @@ #define CONVERSATION_HASH_TABLES_DIALOG_H #include "geometry_state_dialog.h" +#include <epan/wmem/wmem.h> namespace Ui { class ConversationHashTablesDialog; @@ -39,7 +40,7 @@ public: private: Ui::ConversationHashTablesDialog *ui; - const QString hashTableToHtmlTable(const QString table_name, struct _GHashTable *hash_table); + const QString hashTableToHtmlTable(const QString table_name, wmem_map_t *hash_table); }; #endif // CONVERSATION_HASH_TABLES_DIALOG_H |