diff options
author | Gerald Combs <gerald@wireshark.org> | 2011-07-14 23:18:02 +0000 |
---|---|---|
committer | Gerald Combs <gerald@wireshark.org> | 2011-07-14 23:18:02 +0000 |
commit | a533d70be02c874a49d2fa9efbee86538c5338cf (patch) | |
tree | 1ac571fc9727780c83d331ece948e22020d72ebe | |
parent | d25adfda546cc922c58b4c6ec5c6bb01d8c913ed (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.nmake | 1 | ||||
-rw-r--r-- | config.h.win32 | 5 | ||||
-rw-r--r-- | dumpcap.c | 4 | ||||
-rw-r--r-- | gtk/main.c | 4 | ||||
-rw-r--r-- | gtk/main_welcome.c | 206 | ||||
-rw-r--r-- | gtk/main_welcome.h | 2 | ||||
-rw-r--r-- | gtk/menus.c | 17 |
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 */ @@ -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, |