On Windows enable threads everywhere instead of just in dumpcap. If
authorgerald <gerald@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 14 Jul 2011 23:18:02 +0000 (23:18 +0000)
committergerald <gerald@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 14 Jul 2011 23:18:02 +0000 (23:18 +0000)
threads are enabled use them to check the recent file list. Fixes bug
3810.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@38033 f5534014-38df-0310-8fa8-9805f1628bb7

Makefile.nmake
config.h.win32
dumpcap.c
gtk/main.c
gtk/main_welcome.c
gtk/main_welcome.h
gtk/menus.c

index 262710becb49ae47d0c3ba44cf063bae451dbdb1..d9ba2b21e52df2b67f8ea390ed1b630e99da02fe 100644 (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) \
index 454b7e79ea11f29fe392269d8dc71d23e8a56439..f1e05adec57f205ccf2d2405b2454983196789b2 100644 (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 */
index f9447eda264a0dc6c814f7f3efb3f9d3862b683a..694a46b0eecefe902bf75846777d47e8a1a595cf 100644 (file)
--- 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;
index 539675cb5b85b62006ffc9df3d940f10181cbb96..b969ae51995db968086245b4c8b33926da2778f6 100644 (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).
index e8d9fcc6fe7f3c83715dcc34de2c419f3fbc6e65..b7ceb8f4982f8ad16ed792529dfa22ca3d7b8917 100644 (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;
 }
-
index 571d9895b1e43861cc2e065318eddc9178b720b9..c46a148c78b30deccc1fd0f2e4752b1ed01e1060 100644 (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);
index a31df4f8531e019b72edffe2e8c3d054723bb5cb..46d2454927621442404d151bf3c854ae633cf798 100644 (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,