aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2011-07-14 23:18:02 +0000
committerGerald Combs <gerald@wireshark.org>2011-07-14 23:18:02 +0000
commita533d70be02c874a49d2fa9efbee86538c5338cf (patch)
tree1ac571fc9727780c83d331ece948e22020d72ebe
parentd25adfda546cc922c58b4c6ec5c6bb01d8c913ed (diff)
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
-rw-r--r--Makefile.nmake1
-rw-r--r--config.h.win325
-rw-r--r--dumpcap.c4
-rw-r--r--gtk/main.c4
-rw-r--r--gtk/main_welcome.c206
-rw-r--r--gtk/main_welcome.h2
-rw-r--r--gtk/menus.c17
7 files changed, 174 insertions, 65 deletions
diff --git a/Makefile.nmake b/Makefile.nmake
index 262710becb..d9ba2b21e5 100644
--- a/Makefile.nmake
+++ b/Makefile.nmake
@@ -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) \
diff --git a/config.h.win32 b/config.h.win32
index 454b7e79ea..f1e05adec5 100644
--- a/config.h.win32
+++ b/config.h.win32
@@ -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 */
diff --git a/dumpcap.c b/dumpcap.c
index f9447eda26..694a46b0ee 100644
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -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;
diff --git a/gtk/main.c b/gtk/main.c
index 539675cb5b..b969ae5199 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -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).
diff --git a/gtk/main_welcome.c b/gtk/main_welcome.c
index e8d9fcc6fe..b7ceb8f498 100644
--- a/gtk/main_welcome.c
+++ b/gtk/main_welcome.c
@@ -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;
}
-
diff --git a/gtk/main_welcome.h b/gtk/main_welcome.h
index 571d9895b1..c46a148c78 100644
--- a/gtk/main_welcome.h
+++ b/gtk/main_welcome.h
@@ -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);
diff --git a/gtk/menus.c b/gtk/menus.c
index a31df4f853..46d2454927 100644
--- a/gtk/menus.c
+++ b/gtk/menus.c
@@ -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,