On Windows enable threads everywhere instead of just in dumpcap. If

threads are enabled use them to check the recent file list. Fixes bug
3810.

svn path=/trunk/; revision=38033
This commit is contained in:
Gerald Combs 2011-07-14 23:18:02 +00:00
parent d25adfda54
commit a533d70be0
7 changed files with 174 additions and 65 deletions

View File

@ -74,6 +74,7 @@ randpkt_OBJECTS = $(randpkt_SOURCES:.c=.obj)
wireshark_LIBS= wiretap\wiretap-$(WTAP_VERSION).lib \
wsock32.lib user32.lib shell32.lib comctl32.lib \
$(GTHREAD_LIBS) \
$(HHC_LIBS) \
wsutil\libwsutil.lib \
$(GNUTLS_LIBS) \

View File

@ -29,6 +29,9 @@
#define UNICODE 1
#define _UNICODE 1
/* Use threads */
#define USE_THREADS 1
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1
@ -41,6 +44,8 @@
#define HAVE_PLUGINS 1
#define USE_THREADS 1
/* #undef HAVE_SA_LEN */
/* #undef HAVE_MKSTEMP */

View File

@ -134,10 +134,6 @@ FILE *debug_log; /* for logging debug messages to */
/* is defined */
#endif
#ifdef _WIN32
#define USE_THREADS
#endif
static GAsyncQueue *pcap_queue;
static gint64 pcap_queue_bytes;
static gint64 pcap_queue_packets;

View File

@ -2299,6 +2299,10 @@ main(int argc, char *argv[])
optind = optind_initial;
opterr = 1;
#ifdef USE_THREADS
g_thread_init(NULL);
#endif
/* Set the current locale according to the program environment.
* We haven't localized anything, but some GTK widgets are localized
* (the file selection dialogue, for example).

View File

@ -96,6 +96,8 @@ static GtkWidget *if_view = NULL;
static GSList *status_messages = NULL;
static GMutex *recent_mtx = NULL;
/* The "scroll box dynamic" is a (complicated) pseudo widget to */
/* place a vertically list of widgets in (currently the interfaces and recent files). */
/* Once this list get's higher than a specified amount, */
@ -433,10 +435,127 @@ welcome_filename_link_press_cb(GtkWidget *widget _U_, GdkEventButton *event _U_,
return FALSE;
}
typedef struct _recent_item_status {
gchar *filename;
GtkWidget *label;
GObject *menu_item;
GString *str;
gboolean stat_done;
int err;
guint timer;
} recent_item_status;
/*
* Fetch the status of a file.
* This function might be called as a thread. We can't use any drawing
* routines here: http://developer.gnome.org/gdk/2.24/gdk-Threads.html
*/
static void *get_recent_item_status(void *data)
{
recent_item_status *ri_stat = (recent_item_status *) data;
ws_statb64 stat_buf;
int err;
if (!ri_stat) {
return NULL;
}
/*
* Add file size. We use binary prefixes instead of IEC because that's what
* most OSes use.
*/
err = ws_stat64(ri_stat->filename, &stat_buf);
g_mutex_lock(recent_mtx);
ri_stat->err = err;
if(err == 0) {
if (stat_buf.st_size/1024/1024/1024 > 10) {
g_string_append_printf(ri_stat->str, " (%" G_GINT64_MODIFIER "d GB)", (gint64) (stat_buf.st_size/1024/1024/1024));
} else if (stat_buf.st_size/1024/1024 > 10) {
g_string_append_printf(ri_stat->str, " (%" G_GINT64_MODIFIER "d MB)", (gint64) (stat_buf.st_size/1024/1024));
} else if (stat_buf.st_size/1024 > 10) {
g_string_append_printf(ri_stat->str, " (%" G_GINT64_MODIFIER "d KB)", (gint64) (stat_buf.st_size/1024));
} else {
g_string_append_printf(ri_stat->str, " (%" G_GINT64_MODIFIER "d Bytes)", (gint64) (stat_buf.st_size));
}
/* pango format string */
g_string_prepend(ri_stat->str, "<span foreground='blue'>");
g_string_append(ri_stat->str, "</span>");
} else {
g_string_append(ri_stat->str, " [not found]");
}
if (!ri_stat->label) { /* The widget went away while we were busy. */
g_free(ri_stat->filename);
g_string_free(ri_stat->str, TRUE);
g_free(ri_stat);
} else {
ri_stat->stat_done = TRUE;
}
g_mutex_unlock(recent_mtx);
return NULL;
}
/* Timeout callback for recent items */
static gboolean
update_recent_items(gpointer data)
{
recent_item_status *ri_stat = (recent_item_status *) data;
gboolean again = TRUE;
if (!ri_stat) {
return FALSE;
}
g_mutex_lock(recent_mtx);
if (ri_stat->stat_done) {
again = FALSE;
gtk_label_set_markup(GTK_LABEL(ri_stat->label), ri_stat->str->str);
if (ri_stat->err == 0) {
gtk_widget_set_sensitive(ri_stat->label, TRUE);
#ifdef MAIN_MENU_USE_UIMANAGER
gtk_action_set_sensitive(GtkAction *) ri_stat->menu_item, TRUE);
#else
gtk_widget_set_sensitive(GTK_WIDGET(ri_stat->menu_item), TRUE);
#endif
}
ri_stat->timer = 0;
}
/* Else append some sort of Unicode or ASCII animation to the label? */
g_mutex_unlock(recent_mtx);
return again;
}
static void welcome_filename_destroy_cb(GtkWidget *w _U_, gpointer data) {
recent_item_status *ri_stat = (recent_item_status *) data;
if (!ri_stat) {
return;
}
g_mutex_lock(recent_mtx);
if (ri_stat->timer) {
g_source_remove(ri_stat->timer);
ri_stat->timer = 0;
}
g_object_unref(ri_stat->menu_item);
if (ri_stat->stat_done) {
g_free(ri_stat->filename);
g_string_free(ri_stat->str, TRUE);
g_free(ri_stat);
} else {
ri_stat->label = NULL;
}
g_mutex_unlock(recent_mtx);
}
/* create a "file link widget" */
static GtkWidget *
welcome_filename_link_new(const gchar *filename, GtkWidget **label)
welcome_filename_link_new(const gchar *filename, GtkWidget **label, GObject *menu_item)
{
GtkWidget *w;
GtkWidget *eb;
@ -445,10 +564,9 @@ welcome_filename_link_new(const gchar *filename, GtkWidget **label)
glong uni_len;
gsize uni_start, uni_end;
const glong max = 60;
int err;
ws_statb64 stat_buf;
recent_item_status *ri_stat;
/* filename */
/* filename */
str = g_string_new(filename);
uni_len = g_utf8_strlen(str->str, str->len);
@ -463,54 +581,43 @@ welcome_filename_link_new(const gchar *filename, GtkWidget **label)
/* escape the possibly shortened filename before adding pango language */
str_escaped=g_markup_escape_text(str->str, -1);
g_string_free(str, TRUE);
str=g_string_new(str_escaped);
g_free(str_escaped);
/*
* Add file size. We use binary prefixes instead of IEC because that's what
* most OSes use.
*/
err = ws_stat64(filename, &stat_buf);
if(err == 0) {
if (stat_buf.st_size/1024/1024/1024 > 10) {
g_string_append_printf(str, " (%" G_GINT64_MODIFIER "d GB)", (gint64) (stat_buf.st_size/1024/1024/1024));
} else if (stat_buf.st_size/1024/1024 > 10) {
g_string_append_printf(str, " (%" G_GINT64_MODIFIER "d MB)", (gint64) (stat_buf.st_size/1024/1024));
} else if (stat_buf.st_size/1024 > 10) {
g_string_append_printf(str, " (%" G_GINT64_MODIFIER "d KB)", (gint64) (stat_buf.st_size/1024));
} else {
g_string_append_printf(str, " (%" G_GINT64_MODIFIER "d Bytes)", (gint64) (stat_buf.st_size));
}
} else {
g_string_append(str, " [not found]");
}
/* pango format string */
if(err == 0) {
g_string_prepend(str, "<span foreground='blue'>");
g_string_append(str, "</span>");
}
/* label */
w = gtk_label_new(str->str);
w = gtk_label_new(str_escaped);
*label = w;
gtk_label_set_markup(GTK_LABEL(w), str->str);
gtk_misc_set_padding(GTK_MISC(w), 5, 2);
gtk_misc_set_alignment (GTK_MISC(w), 0.0f, 0.0f);
gtk_widget_set_sensitive(w, FALSE);
ri_stat = g_malloc(sizeof(recent_item_status));
ri_stat->filename = g_strdup(filename);
ri_stat->label = w;
ri_stat->menu_item = menu_item;
ri_stat->str = g_string_new(str_escaped);
ri_stat->stat_done = FALSE;
ri_stat->timer = 0;
g_object_ref(G_OBJECT(menu_item));
g_signal_connect(w, "destroy", G_CALLBACK(welcome_filename_destroy_cb), ri_stat);
g_free(str_escaped);
#ifdef USE_THREADS
g_thread_create(get_recent_item_status, ri_stat, FALSE, NULL);
ri_stat->timer = g_timeout_add(200, update_recent_items, ri_stat);
#else
get_recent_item_status(ri_stat);
update_recent_items(ri_stat);
#endif
/* event box */
eb = gtk_event_box_new();
gtk_widget_modify_bg(eb, GTK_STATE_NORMAL, &topic_item_idle_bg);
gtk_container_add(GTK_CONTAINER(eb), w);
gtk_widget_set_tooltip_text(eb, filename);
if(err != 0) {
gtk_widget_set_sensitive(w, FALSE);
}
gtk_widget_set_tooltip_text(eb, filename);
g_signal_connect(eb, "enter-notify-event", G_CALLBACK(welcome_item_enter_cb), w);
g_signal_connect(eb, "leave-notify-event", G_CALLBACK(welcome_item_leave_cb), w);
g_signal_connect(eb, "button-press-event", G_CALLBACK(welcome_filename_link_press_cb), (gchar *) filename);
g_string_free(str, TRUE);
return eb;
}
@ -541,16 +648,14 @@ main_welcome_reset_recent_capture_files(void)
/* add a new file to the list of recent files */
void
main_welcome_add_recent_capture_files(const char *widget_cf_name)
main_welcome_add_recent_capture_file(const char *widget_cf_name, GObject *menu_item)
{
GtkWidget *w;
GtkWidget *child_box;
GtkWidget *label;
w = welcome_filename_link_new(widget_cf_name, &label);
gtk_widget_modify_bg(w, GTK_STATE_NORMAL, &topic_item_idle_bg);
gtk_misc_set_alignment (GTK_MISC(label), 0.0f, 0.0f);
w = welcome_filename_link_new(widget_cf_name, &label, menu_item);
child_box = scroll_box_dynamic_add(welcome_file_panel_vb);
gtk_box_pack_start(GTK_BOX(child_box), w, FALSE, FALSE, 0);
gtk_widget_show_all(w);
@ -565,7 +670,7 @@ static gboolean select_current_ifaces(GtkTreeModel *model,
{
guint i;
gchar *if_name;
GtkTreeSelection *selection = (GtkTreeSelection *)userdata;
gtk_tree_model_get (model, iter, 2, &if_name, -1);
if (global_capture_opts.ifaces->len > 0) {
@ -696,7 +801,7 @@ static void make_selections_array(GtkTreeModel *model,
if_info_t *if_info;
gtk_tree_model_get (model, iter, 2, &if_name, -1);
if_list = capture_interface_list(&err, NULL);
if_list = g_list_sort (if_list, if_list_comparator_alph);
if (g_list_length(if_list) > 0) {
@ -789,7 +894,7 @@ static void capture_if_start(GtkWidget *w _U_, gpointer data _U_)
#endif
capture_start_cb(NULL, NULL);
}
void capture_if_cb_prep(GtkWidget *w _U_, gpointer d _U_)
{
GtkTreeSelection *entry;
@ -903,12 +1008,12 @@ welcome_new(void)
"Same as Capture/Interfaces menu or toolbar item",
welcome_button_callback_helper, capture_if_cb_prep);
gtk_box_pack_start(GTK_BOX(topic_to_fill), item_hb, FALSE, FALSE, 5);
swindow = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_size_request(swindow, FALSE, 100);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swindow), GTK_SHADOW_IN);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
if_view = gtk_tree_view_new ();
g_object_set(GTK_OBJECT(if_view), "headers-visible", FALSE, NULL);
g_object_set_data(G_OBJECT(welcome_hb), TREE_VIEW_INTERFACES, if_view);
@ -974,7 +1079,7 @@ welcome_new(void)
gtk_misc_set_alignment (GTK_MISC(w), 0.0f, 0.0f);
gtk_box_pack_start(GTK_BOX(topic_to_fill), w, FALSE, FALSE, 5);
}
free_interface_list(if_list);
/* capture help topic */
@ -1105,6 +1210,7 @@ welcome_new(void)
welcome_eb);
gtk_widget_show_all(welcome_scrollw);
recent_mtx = g_mutex_new();
return welcome_scrollw;
}

View File

@ -32,7 +32,7 @@ GtkWidget *welcome_new(void);
void main_welcome_reset_recent_capture_files(void);
/* add a new file to the list of recently used files */
void main_welcome_add_recent_capture_files(const char *widget_cf_name);
void main_welcome_add_recent_capture_file(const char *widget_cf_name, GObject *menu_item);
/* reload the list of interfaces */
void welcome_if_panel_reload(void);

View File

@ -4574,7 +4574,8 @@ update_menu_recent_capture_file1(GtkWidget *widget, gpointer cnt) {
/* if this menu item is a file, count it */
if (widget_cf_name) {
(*(guint *)cnt)++;
main_welcome_add_recent_capture_files(widget_cf_name);
gtk_widget_set_sensitive(widget, FALSE);
main_welcome_add_recent_capture_file(widget_cf_name, G_OBJECT(widget));
}
}
@ -4594,11 +4595,9 @@ update_menu_recent_capture_file(GtkWidget *submenu_recent_files) {
/* Empty list */
menu_item = gtk_menu_item_new_with_label("No recently used files");
gtk_menu_shell_append (GTK_MENU_SHELL(submenu_recent_files), menu_item);
gtk_widget_set_sensitive(gtk_menu_get_attach_widget(GTK_MENU(menu_item)), FALSE);
gtk_widget_show (menu_item);
}
/* make parent menu item sensitive only, if we have any valid files in the list */
set_menu_sensitivity_old(MENU_RECENT_FILES_PATH_OLD, cnt);
}
#endif /* MAIN_MENU_USE_UIMANAGER */
@ -4759,7 +4758,6 @@ add_recent_items (guint merge_id, GtkUIManager *ui_manager)
GtkAction *action;
GtkWidget *submenu_recent_files;
GList *items, *l;
gchar *name;
gchar *action_name;
guint i;
@ -4787,6 +4785,7 @@ add_recent_items (guint merge_id, GtkUIManager *ui_manager)
"sensitive", FALSE,
NULL);
gtk_action_group_add_action (action_group, action);
gtk_action_set_sensitive(action, FALSE);
g_object_unref (action);
gtk_ui_manager_add_ui (ui_manager, merge_id,
@ -4804,8 +4803,7 @@ add_recent_items (guint merge_id, GtkUIManager *ui_manager)
i +=1, l = l->next)
{
gchar *item_name = l->data;
name = g_strdup_printf ("recent-info-%u", i);
action_name = g_strdup (name);
action_name = g_strdup_printf ("recent-info-%u", i);
action = g_object_new (GTK_TYPE_ACTION,
"name", action_name,
@ -4819,16 +4817,15 @@ add_recent_items (guint merge_id, GtkUIManager *ui_manager)
gtk_ui_manager_add_ui (ui_manager, merge_id,
"/Menubar/FileMenu/OpenRecent/RecentFiles",
name,
action_name,
action_name,
GTK_UI_MANAGER_MENUITEM,
FALSE);
/* Add the file name to the recent files list on the Welcome screen */
main_welcome_add_recent_capture_files(item_name);
main_welcome_add_recent_capture_file(item_name, G_OBJECT(action));
g_free (action_name);
g_free (name);
}
/* Add a Separator */
gtk_ui_manager_add_ui (ui_manager, merge_id,