Don't do file-read progress bar updates with a timeout; instead, update
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Sat, 28 Aug 1999 01:51:58 +0000 (01:51 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Sat, 28 Aug 1999 01:51:58 +0000 (01:51 +0000)
the progress bar up to 100 times, as we get another percent closer to
completion.  That reduces the number of times we run the GTK+ main loop;
that main loop may do a "select()" or "poll()" or FIONREAD "ioctl" to
check for input from the X server, adding to the CPU overhead of reading
a file.

The packet filtering progress bar is already updated in a similar
fashion; make it also do up to 100 updates.

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

ethereal.c
ethereal.h
file.c
file.h

index cf342c03d71b380bec61822a2c5227742efc1f5a..15baf5c0fb8dee567936a45f7f7f14dd6120d3e8 100644 (file)
@@ -1,6 +1,6 @@
 /* ethereal.c
  *
- * $Id: ethereal.c,v 1.108 1999/08/26 06:20:49 gram Exp $
+ * $Id: ethereal.c,v 1.109 1999/08/28 01:51:58 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -176,15 +176,6 @@ about_ethereal( GtkWidget *w, gpointer data ) {
                 VERSION, comp_info_str);
 }
 
-/* Update the progress bar */
-gint
-file_progress_cb(gpointer p) {
-  capture_file *cf = (capture_file*) p;
-  gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar),
-    (gfloat) ftell(cf->fh) / (gfloat) cf->f_len);
-  return TRUE;
-}
-
 /* Follow the TCP stream, if any, to which the last packet that we called
    a dissection routine on belongs (this might be the most recently
    selected packet, or it might be the last packet in the file). */
index c51b57dfc25a29eb67db153cca9cd7e65ccd6f21..049bc7380c654f20a21455763ffac2e8a442c64f 100644 (file)
@@ -1,7 +1,7 @@
 /* ethereal.h
  * Global defines, etc.
  *
- * $Id: ethereal.h,v 1.22 1999/08/22 00:47:44 guy Exp $
+ * $Id: ethereal.h,v 1.23 1999/08/28 01:51:58 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -82,7 +82,6 @@ extern GtkStyle *item_style;
 
 void about_ethereal( GtkWidget *, gpointer);
 void blank_packetinfo();
-gint file_progress_cb(gpointer);
 void follow_stream_cb( GtkWidget *, gpointer);
 void match_selected_cb( GtkWidget *, gpointer);
 void file_open_cmd_cb(GtkWidget *, gpointer);
diff --git a/file.c b/file.c
index 69fb4281620f4f6d3aab1a91e778926318c01143..8f7b07941248a35b277dcfd665148ccabc4dbfa3 100644 (file)
--- a/file.c
+++ b/file.c
@@ -1,7 +1,7 @@
 /* file.c
  * File I/O routines
  *
- * $Id: file.c,v 1.83 1999/08/26 07:01:42 gram Exp $
+ * $Id: file.c,v 1.84 1999/08/28 01:51:57 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -97,7 +97,8 @@ static void wtap_dispatch_cb(u_char *, const struct wtap_pkthdr *, int,
 static void freeze_clist(capture_file *cf);
 static void thaw_clist(capture_file *cf);
 
-static gint dfilter_progress_cb(gpointer p);
+/* Update the progress bar this many times when reading a file. */
+#define N_PROGBAR_UPDATES      100
 
 int
 open_cap_file(char *fname, capture_file *cf) {
@@ -139,6 +140,9 @@ open_cap_file(char *fname, capture_file *cf) {
   cf->esec      = 0;
   cf->eusec     = 0;
   cf->snap      = wtap_snapshot_length(cf->wth);
+  cf->update_progbar = FALSE;
+  cf->progbar_quantum = 0;
+  cf->progbar_nextstep = 0;
   firstsec = 0, firstusec = 0;
   prevsec = 0, prevusec = 0;
  
@@ -196,7 +200,6 @@ read_cap_file(capture_file *cf) {
   gchar  *done_fmt = " File: %s  Drops: %d";
   int     success;
   int     err;
-  gint    timeout;
   size_t  msg_len;
   char   *errmsg;
   char    errmsg_errno[1024+1];
@@ -210,8 +213,13 @@ read_cap_file(capture_file *cf) {
   load_msg = g_malloc(strlen(name_ptr) + strlen(load_fmt) + 2);
   sprintf(load_msg, load_fmt, name_ptr);
   gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, load_msg);
-  
-  timeout = gtk_timeout_add(250, file_progress_cb, (gpointer) cf);
+
+  cf->update_progbar = TRUE;
+  /* Update the progress bar when it gets to this value. */
+  cf->progbar_nextstep = 0;
+  /* When we reach the value that triggers a progress bar update,
+     bump that value by this amount. */
+  cf->progbar_quantum = cf->f_len/N_PROGBAR_UPDATES;
 
   freeze_clist(cf);
   proto_tree_is_visible = FALSE;
@@ -221,7 +229,6 @@ read_cap_file(capture_file *cf) {
   cf->fh = fopen(cf->filename, "r");
   thaw_clist(cf);
   
-  gtk_timeout_remove(timeout);
   gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar), 0);
 
   gtk_statusbar_pop(GTK_STATUSBAR(info_bar), file_ctx);
@@ -599,8 +606,23 @@ wtap_dispatch_cb(u_char *user, const struct wtap_pkthdr *phdr, int offset,
   proto_tree   *protocol_tree;
   frame_data   *plist_end;
 
-  while (gtk_events_pending())
-    gtk_main_iteration();
+  /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
+     when we update it, we have to run the GTK+ main loop to get it
+     to repaint what's pending, and doing so may involve an "ioctl()"
+     to see if there's any pending input from an X server, and doing
+     that for every packet can be costly, especially on a big file.
+     
+     Do so only if we were told to do so; when reading a capture file
+     being updated by a live capture, we don't do so (as we're not
+     "done" until the capture stops, so we don't know how close to
+     "done" we are. */
+  if (cf->update_progbar && offset >= cf->progbar_nextstep) {
+    gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar),
+      (gfloat) ftell(cf->fh) / (gfloat) cf->f_len);
+    cf->progbar_nextstep += cf->progbar_quantum;
+    while (gtk_events_pending())
+      gtk_main_iteration();
+  }
 
   /* Allocate the next list entry, and add it to the list. */
   fdata = (frame_data *) g_malloc(sizeof(frame_data));
@@ -641,8 +663,9 @@ wtap_dispatch_cb(u_char *user, const struct wtap_pkthdr *phdr, int offset,
 void
 filter_packets(capture_file *cf)
 {
-/*  gint timeout;*/
   frame_data *fd;
+  guint32 progbar_quantum;
+  guint32 progbar_nextstep;
 
   if (cf->dfilter == NULL) {
        dfilter_clear_filter(cf->dfcode);
@@ -680,20 +703,38 @@ filter_packets(capture_file *cf)
 
   proto_tree_is_visible = FALSE;
 
-/*  timeout = gtk_timeout_add(250, dfilter_progress_cb, cf);*/
+  /* Update the progress bar when it gets to this value. */
+  progbar_nextstep = 0;
+  /* When we reach the value that triggers a progress bar update,
+     bump that value by this amount. */
+  progbar_quantum = cf->unfiltered_count/N_PROGBAR_UPDATES;
+
   for (fd = cf->plist; fd != NULL; fd = fd->next) {
+    /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
+       when we update it, we have to run the GTK+ main loop to get it
+       to repaint what's pending, and doing so may involve an "ioctl()"
+       to see if there's any pending input from an X server, and doing
+       that for every packet can be costly, especially on a big file. */
+    if (cf->count >= progbar_nextstep) {
+      /* let's not divide by zero. I should never be started
+       * with unfiltered_count == 0, so let's assert that
+       */
+      g_assert(cf->unfiltered_count > 0);
+
+      gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar),
+        (gfloat) cf->count / cf->unfiltered_count);
+      progbar_nextstep += progbar_quantum;
+      while (gtk_events_pending())
+        gtk_main_iteration();
+    }
+
     cf->count++;
 
     fseek(cf->fh, fd->file_off, SEEK_SET);
     fread(cf->pd, sizeof(guint8), fd->cap_len, cf->fh);
 
     add_packet_to_packet_list(fd, cf, cf->pd);
-
-    if (cf->count % 20 == 0) {
-      dfilter_progress_cb(cf);
-    }
   }
-/*  gtk_timeout_remove(timeout);*/
  
   gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar), 0);
 
@@ -709,27 +750,6 @@ filter_packets(capture_file *cf)
   gtk_clist_thaw(GTK_CLIST(packet_list));
 }
 
-/* Update the progress bar */
-static gint
-dfilter_progress_cb(gpointer p) {
-  capture_file *cf = (capture_file*)p;
-
-  /* let's not divide by zero. I should never be started
-   * with unfiltered_count == 0, so let's assert that
-   */
-  g_assert(cf->unfiltered_count > 0);
-
-  gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar),
-    (gfloat) cf->count / cf->unfiltered_count);
-
-  /* Have GTK+ repaint what is pending */
-  while (gtk_events_pending ()) {
-         gtk_main_iteration();
-  }
-  return TRUE;
-}
-
-
 int
 print_packets(capture_file *cf, int to_file, const char *dest)
 {
diff --git a/file.h b/file.h
index 7b9da7f7ae19595cc660cb2daaac45687b655ef4..5be11cfe5e55b489c147c280c4076c15445fa046 100644 (file)
--- a/file.h
+++ b/file.h
@@ -1,7 +1,7 @@
 /* file.h
  * Definitions for file structures and routines
  *
- * $Id: file.h,v 1.41 1999/08/24 16:27:23 gram Exp $
+ * $Id: file.h,v 1.42 1999/08/28 01:51:57 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -63,6 +63,9 @@ typedef struct _capture_file {
   guint32      esec;      /* Elapsed seconds */
   guint32      eusec;     /* Elapsed microseconds */
   guint32      snap;      /* Captured packet length */
+  gboolean     update_progbar; /* TRUE if we should update the progress bar */
+  long         progbar_quantum; /* Number of bytes read per progress bar update */
+  long         progbar_nextstep; /* Next point at which to update progress bar */
   gchar       *iface;     /* Interface */
   gchar       *save_file; /* File that user saved capture to */
   int          save_file_fd; /* File descriptor for saved file */