]> sjero.net Git - wget/commitdiff
[svn] Extract timers to a separate file.
authorhniksic <devnull@localhost>
Thu, 7 Apr 2005 21:37:22 +0000 (14:37 -0700)
committerhniksic <devnull@localhost>
Thu, 7 Apr 2005 21:37:22 +0000 (14:37 -0700)
src/ChangeLog
src/Makefile.in
src/convert.c
src/convert.h
src/ftp-ls.c
src/init.c
src/ptimer.c [new file with mode: 0644]
src/ptimer.h [new file with mode: 0644]
src/retr.c
src/utils.c
src/utils.h

index a63c33739aa23b8bcf004879645fafe9427247e9..8242627cff50bee3525be31bfd055503f83e1b35 100644 (file)
@@ -1,3 +1,8 @@
+2005-04-07  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * ptimer.c: New file.  Move the "wtimer" functions from utils.c to
+       this file and rename them to ptimer_.
+
 2005-04-07  Hrvoje Niksic  <hniksic@xemacs.org>
 
        * host.c (NO_ADDRESS): Define NO_ADDRESS only after the system
index e0acdc809703c69d5a683256e874cf1a12ad58bc..048b9a78f5f463421dfec05c907fe3ee219aba48 100644 (file)
@@ -76,7 +76,7 @@ GETOPT_OBJ = @GETOPT_OBJ@
 OBJ = $(ALLOCA) cmpt$o connect$o convert$o cookies$o              \
       ftp$o ftp-basic$o ftp-ls$o $(OPIE_OBJ) $(GETOPT_OBJ) hash$o \
       host$o html-parse$o html-url$o http$o $(NTLM_OBJ) init$o    \
-      log$o main$o $(MD5_OBJ) netrc$o progress$o recur$o          \
+      log$o main$o $(MD5_OBJ) netrc$o progress$o ptimer$o recur$o \
       res$o retr$o safe-ctype$o snprintf$o $(SSL_OBJ) url$o       \
       utils$o version$o xmalloc$o 
 
index ed567124a2c8d4c67936a292033b244046c72bf9..33981a3eab72793f59034911e406b25cd644899c 100644 (file)
@@ -49,6 +49,7 @@ so, delete this exception statement from your version.  */
 #include "recur.h"
 #include "utils.h"
 #include "hash.h"
+#include "ptimer.h"
 
 static struct hash_table *dl_file_url_map;
 struct hash_table *dl_url_file_map;
@@ -81,7 +82,7 @@ convert_all_links (void)
   double secs;
   int file_count = 0;
 
-  struct wget_timer *timer = wtimer_new ();
+  struct ptimer *timer = ptimer_new ();
 
   int cnt;
   char **file_array;
@@ -170,9 +171,8 @@ convert_all_links (void)
       free_urlpos (urls);
     }
 
-  wtimer_update (timer);
-  secs = wtimer_read (timer) / 1000;
-  wtimer_delete (timer);
+  secs = ptimer_measure (timer) / 1000;
+  ptimer_destroy (timer);
   logprintf (LOG_VERBOSE, _("Converted %d files in %.*f seconds.\n"),
             file_count, secs < 10 ? 3 : 1, secs);
 }
@@ -834,8 +834,10 @@ register_html (const char *url, const char *file)
   string_set_add (downloaded_html_set, file);
 }
 
-/* Cleanup the data structures associated with recursive retrieving
-   (the variables above).  */
+static void downloaded_files_free PARAMS ((void));
+
+/* Cleanup the data structures associated with this file.  */
+
 void
 convert_cleanup (void)
 {
@@ -853,6 +855,7 @@ convert_cleanup (void)
     }
   if (downloaded_html_set)
     string_set_free (downloaded_html_set);
+  downloaded_files_free ();
 }
 \f
 /* Book-keeping code for downloaded files that enables extension
@@ -943,7 +946,7 @@ df_free_mapper (void *key, void *value, void *ignored)
   return 0;
 }
 
-void
+static void
 downloaded_files_free (void)
 {
   if (downloaded_files_hash)
@@ -953,3 +956,75 @@ downloaded_files_free (void)
       downloaded_files_hash = NULL;
     }
 }
+\f
+/* The function returns the pointer to the malloc-ed quoted version of
+   string s.  It will recognize and quote numeric and special graphic
+   entities, as per RFC1866:
+
+   `&' -> `&amp;'
+   `<' -> `&lt;'
+   `>' -> `&gt;'
+   `"' -> `&quot;'
+   SP  -> `&#32;'
+
+   No other entities are recognized or replaced.  */
+char *
+html_quote_string (const char *s)
+{
+  const char *b = s;
+  char *p, *res;
+  int i;
+
+  /* Pass through the string, and count the new size.  */
+  for (i = 0; *s; s++, i++)
+    {
+      if (*s == '&')
+       i += 4;                 /* `amp;' */
+      else if (*s == '<' || *s == '>')
+       i += 3;                 /* `lt;' and `gt;' */
+      else if (*s == '\"')
+       i += 5;                 /* `quot;' */
+      else if (*s == ' ')
+       i += 4;                 /* #32; */
+    }
+  res = (char *)xmalloc (i + 1);
+  s = b;
+  for (p = res; *s; s++)
+    {
+      switch (*s)
+       {
+       case '&':
+         *p++ = '&';
+         *p++ = 'a';
+         *p++ = 'm';
+         *p++ = 'p';
+         *p++ = ';';
+         break;
+       case '<': case '>':
+         *p++ = '&';
+         *p++ = (*s == '<' ? 'l' : 'g');
+         *p++ = 't';
+         *p++ = ';';
+         break;
+       case '\"':
+         *p++ = '&';
+         *p++ = 'q';
+         *p++ = 'u';
+         *p++ = 'o';
+         *p++ = 't';
+         *p++ = ';';
+         break;
+       case ' ':
+         *p++ = '&';
+         *p++ = '#';
+         *p++ = '3';
+         *p++ = '2';
+         *p++ = ';';
+         break;
+       default:
+         *p++ = *s;
+       }
+    }
+  *p = '\0';
+  return res;
+}
index 53b0c97ad94c7dcbe2ee9f11a3c02e6355515ae1..bbbd73786cb291c101111ea5ca31bce99315d1ed 100644 (file)
@@ -101,4 +101,6 @@ void register_delete_file PARAMS ((const char *));
 void convert_all_links PARAMS ((void));
 void convert_cleanup PARAMS ((void));
 
+char *html_quote_string PARAMS ((const char *));
+
 #endif /* CONVERT_H */
index 913302502b7d8d187fde973c9b755bb0506a9f95..dd703dfd193d9e3773fd8745959028de9b2d8554 100644 (file)
@@ -47,6 +47,7 @@ so, delete this exception statement from your version.  */
 #include "utils.h"
 #include "ftp.h"
 #include "url.h"
+#include "convert.h"           /* for html_quote_string prototype */
 
 extern FILE *output_stream;
 
index 142ff81dd84d6a2fa2edddb596b8df0fb016ae89..3fb9aa23948cef0f1121f7c4bc797b699199dedf 100644 (file)
@@ -55,6 +55,7 @@ so, delete this exception statement from your version.  */
 #include "progress.h"
 #include "recur.h"             /* for INFINITE_RECURSION */
 #include "convert.h"           /* for convert_cleanup */
+#include "res.h"               /* for res_cleanup */
 
 #ifndef errno
 extern int errno;
@@ -1300,8 +1301,6 @@ check_user_specified_header (const char *s)
 }
 \f
 void cleanup_html_url PARAMS ((void));
-void res_cleanup PARAMS ((void));
-void downloaded_files_free PARAMS ((void));
 void http_cleanup PARAMS ((void));
 
 
@@ -1332,7 +1331,6 @@ cleanup (void)
   res_cleanup ();
   http_cleanup ();
   cleanup_html_url ();
-  downloaded_files_free ();
   host_cleanup ();
   log_cleanup ();
 
diff --git a/src/ptimer.c b/src/ptimer.c
new file mode 100644 (file)
index 0000000..e697921
--- /dev/null
@@ -0,0 +1,412 @@
+/* Portable timers.
+   Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Wget.
+
+GNU Wget is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+GNU Wget is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Wget; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+In addition, as a special exception, the Free Software Foundation
+gives permission to link the code of its release of Wget with the
+OpenSSL project's "OpenSSL" library (or with modified versions of it
+that use the same license as the "OpenSSL" library), and distribute
+the linked executables.  You must obey the GNU General Public License
+in all respects for all of the code used other than "OpenSSL".  If you
+modify this file, you may extend this exception to your version of the
+file, but you are not obligated to do so.  If you do not wish to do
+so, delete this exception statement from your version.  */
+
+/* This file implements "portable timers" (ptimers), objects that
+   measure elapsed time using the primitives most appropriate for the
+   underlying operating system.  The entry points are:
+
+     ptimer_new     -- creates a timer.
+     ptimer_reset   -- resets the timer's elapsed time to zero.
+     ptimer_measure -- measure and return the time elapsed since
+                      creation or last reset.
+     ptimer_read    -- reads the last measured elapsed value.
+     ptimer_destroy -- destroy the timer.
+     ptimer_granularity -- returns the approximate granularity of the timers.
+
+   Timers operate in milliseconds, but return floating point values
+   that can be more precise.  For example, to measure the time it
+   takes to run a loop, you can use something like:
+
+     ptimer *tmr = ptimer_new ();
+     while (...)
+       ... loop ...
+     double msecs = ptimer_measure ();
+     printf ("The loop took %.2f ms\n", msecs);  */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else  /* not HAVE_STRING_H */
+# include <strings.h>
+#endif /* not HAVE_STRING_H */
+#include <sys/types.h>
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <assert.h>
+
+#include "wget.h"
+#include "ptimer.h"
+
+#ifndef errno
+extern int errno;
+#endif
+
+/* Depending on the OS and availability of gettimeofday(), one and
+   only one of PTIMER_WINDOWS, PTIMER_GETTIMEOFDAY, or PTIMER_TIME will
+   be defined.
+
+   Virtually all modern Unix systems will define PTIMER_GETTIMEOFDAY;
+   Windows will use PTIMER_WINDOWS.  PTIMER_TIME is a catch-all method
+   for non-Windows systems without gettimeofday, such as DOS or really
+   old Unix-like systems.  */
+
+#undef PTIMER_POSIX
+#undef PTIMER_GETTIMEOFDAY
+#undef PTIMER_TIME
+#undef PTIMER_WINDOWS
+
+#ifdef WINDOWS
+# define PTIMER_WINDOWS                /* use Windows timers */
+#else
+# if _POSIX_TIMERS > 0
+#  define PTIMER_POSIX         /* use POSIX timers (clock_gettime) */
+# else
+#  ifdef HAVE_GETTIMEOFDAY
+#   define PTIMER_GETTIMEOFDAY /* use gettimeofday */
+#  else
+#   define PTIMER_TIME
+#  endif
+# endif
+#endif
+
+/* The type ptimer_system_time holds system time. */
+
+#ifdef PTIMER_POSIX
+typedef struct timespec ptimer_system_time;
+#endif
+
+#ifdef PTIMER_GETTIMEOFDAY
+typedef struct timeval ptimer_system_time;
+#endif
+
+#ifdef PTIMER_TIME
+typedef time_t ptimer_system_time;
+#endif
+
+#ifdef PTIMER_WINDOWS
+typedef union {
+  DWORD lores;          /* In case GetTickCount is used */
+  LARGE_INTEGER hires;  /* In case high-resolution timer is used */
+} ptimer_system_time;
+#endif
+
+struct ptimer {
+  /* Whether the start time has been set. */
+  int initialized;
+
+  /* The starting point in time which, subtracted from the current
+     time, yields elapsed time. */
+  ptimer_system_time start;
+
+  /* The most recent elapsed time, calculated by ptimer_measure().
+     Measured in milliseconds.  */
+  double elapsed_last;
+
+  /* Approximately, the time elapsed between the true start of the
+     measurement and the time represented by START.  */
+  double elapsed_pre_start;
+};
+
+#ifdef PTIMER_WINDOWS
+/* Whether high-resolution timers are used.  Set by ptimer_initialize_once
+   the first time ptimer_allocate is called. */
+static int windows_hires_timers;
+
+/* Frequency of high-resolution timers -- number of updates per
+   millisecond.  Calculated the first time ptimer_allocate is called
+   provided that high-resolution timers are available. */
+static double windows_hires_msfreq;
+
+/* The first time a timer is created, determine whether to use
+   high-resolution timers. */
+
+static void
+ptimer_init (void)
+{
+  LARGE_INTEGER freq;
+  freq.QuadPart = 0;
+  QueryPerformanceFrequency (&freq);
+  if (freq.QuadPart != 0)
+    {
+      windows_hires_timers = 1;
+      windows_hires_msfreq = (double) freq.QuadPart / 1000.0;
+    }
+}
+#define PTIMER_INIT_DEFINED
+#endif /* PTIMER_WINDOWS */
+
+#ifdef PTIMER_POSIX
+
+/* clock_id to use for POSIX clocks.  This tries to use
+   CLOCK_MONOTONIC where available, CLOCK_REALTIME otherwise.  */
+static int posix_clock_id;
+
+/* Resolution of the clock, in milliseconds. */
+static double posix_resolution;
+
+/* Check whether the monotonic clock is available, and retrieve POSIX
+   timer resolution.  */
+
+static void
+ptimer_init (void)
+{
+  struct timespec res;
+
+#if _POSIX_MONOTONIC_CLOCK > 0
+  if (sysconf (_SC_MONOTONIC_CLOCK) > 0)
+    posix_clock_id = CLOCK_MONOTONIC;
+  else
+#endif
+    posix_clock_id = CLOCK_REALTIME;
+
+  if (clock_getres (posix_clock_id, &res) < 0)
+    {
+      logprintf (LOG_NOTQUIET, _("Cannot read clock resolution: %s\n"),
+                strerror (errno));
+      /* Assume 1 ms resolution */
+      res.tv_sec = 0;
+      res.tv_nsec = 1000000;
+    }
+
+  posix_resolution = res.tv_sec * 1000.0 + res.tv_nsec / 1000000.0;
+  /* Guard against clock_getres reporting 0 resolution; after all, it
+     can be used for division.  */
+  if (posix_resolution == 0)
+    posix_resolution = 1;
+}
+#define PTIMER_INIT_DEFINED
+#endif
+
+/* Allocate a timer.  Calling ptimer_read on the timer will return
+   zero.  It is not legal to call ptimer_measure with a freshly
+   allocated timer -- use ptimer_reset first.  */
+
+struct ptimer *
+ptimer_allocate (void)
+{
+  struct ptimer *wt;
+
+#ifdef PTIMER_INIT_DEFINED
+  static int init_done;
+  if (!init_done)
+    {
+      init_done = 1;
+      ptimer_init ();
+    }
+#endif
+
+  wt = xnew0 (struct ptimer);
+  return wt;
+}
+
+/* Allocate a new timer and reset it.  Return the new timer. */
+
+struct ptimer *
+ptimer_new (void)
+{
+  struct ptimer *wt = ptimer_allocate ();
+  ptimer_reset (wt);
+  return wt;
+}
+
+/* Free the resources associated with the timer.  Its further use is
+   prohibited.  */
+
+void
+ptimer_destroy (struct ptimer *wt)
+{
+  xfree (wt);
+}
+
+/* Store system time to PST.  */
+
+static void
+ptimer_sys_set (ptimer_system_time *pst)
+{
+#ifdef PTIMER_POSIX
+  clock_gettime (posix_clock_id, pst);
+#endif
+
+#ifdef PTIMER_GETTIMEOFDAY
+  gettimeofday (pst, NULL);
+#endif
+
+#ifdef PTIMER_TIME
+  time (pst);
+#endif
+
+#ifdef PTIMER_WINDOWS
+  if (windows_hires_timers)
+    {
+      QueryPerformanceCounter (&pst->hires);
+    }
+  else
+    {
+      /* Where hires counters are not available, use GetTickCount rather
+         GetSystemTime, because it is unaffected by clock skew and simpler
+         to use.  Note that overflows don't affect us because we never use
+         absolute values of the ticker, only the differences.  */
+      pst->lores = GetTickCount ();
+    }
+#endif
+}
+
+/* Reset timer WT.  This establishes the starting point from which
+   ptimer_read() will return the number of elapsed milliseconds.
+   It is allowed to reset a previously used timer.  */
+
+void
+ptimer_reset (struct ptimer *wt)
+{
+  /* Set the start time to the current time. */
+  ptimer_sys_set (&wt->start);
+  wt->elapsed_last = 0;
+  wt->elapsed_pre_start = 0;
+  wt->initialized = 1;
+}
+
+static double
+ptimer_diff (ptimer_system_time *pst1, ptimer_system_time *pst2)
+{
+#ifdef PTIMER_POSIX
+  return ((pst1->tv_sec - pst2->tv_sec) * 1000.0
+         + (pst1->tv_nsec - pst2->tv_nsec) / 1000000.0);
+#endif
+
+#ifdef PTIMER_GETTIMEOFDAY
+  return ((pst1->tv_sec - pst2->tv_sec) * 1000.0
+         + (pst1->tv_usec - pst2->tv_usec) / 1000.0);
+#endif
+
+#ifdef PTIMER_TIME
+  return 1000 * (*pst1 - *pst2);
+#endif
+
+#ifdef WINDOWS
+  if (using_hires_timers)
+    return (pst1->hires.QuadPart - pst2->hires.QuadPart) / windows_hires_msfreq;
+  else
+    return pst1->lores - pst2->lores;
+#endif
+}
+
+/* Measure the elapsed time since timer creation/reset and return it
+   to the caller.  The value remains stored for further reads by
+   ptimer_read.
+
+   This function causes the timer to call gettimeofday (or time(),
+   etc.) to update its idea of current time.  To get the elapsed
+   interval in milliseconds, use ptimer_read.
+
+   This function handles clock skew, i.e. time that moves backwards is
+   ignored.  */
+
+double
+ptimer_measure (struct ptimer *wt)
+{
+  ptimer_system_time now;
+  double elapsed;
+
+  assert (wt->initialized != 0);
+
+  ptimer_sys_set (&now);
+  elapsed = wt->elapsed_pre_start + ptimer_diff (&now, &wt->start);
+
+  /* Ideally we'd just return the difference between NOW and
+     wt->start.  However, the system timer can be set back, and we
+     could return a value smaller than when we were last called, even
+     a negative value.  Both of these would confuse the callers, which
+     expect us to return monotonically nondecreasing values.
+
+     Therefore: if ELAPSED is smaller than its previous known value,
+     we reset wt->start to the current time and effectively start
+     measuring from this point.  But since we don't want the elapsed
+     value to start from zero, we set elapsed_pre_start to the last
+     elapsed time and increment all future calculations by that
+     amount.
+
+     This cannot happen with Windows and CLOCK_MONOTONIC timers, but
+     the check is not expensive.  */
+
+  if (elapsed < wt->elapsed_last)
+    {
+      wt->start = now;
+      wt->elapsed_pre_start = wt->elapsed_last;
+      elapsed = wt->elapsed_last;
+    }
+
+  wt->elapsed_last = elapsed;
+  return elapsed;
+}
+
+/* Return the elapsed time in milliseconds between the last call to
+   ptimer_reset and the last call to ptimer_update.  */
+
+double
+ptimer_read (const struct ptimer *wt)
+{
+  return wt->elapsed_last;
+}
+
+/* Return the assessed granularity of the timer implementation, in
+   milliseconds.  This is used by code that tries to substitute a
+   better value for timers that have returned zero.  */
+
+double
+ptimer_granularity (void)
+{
+#ifdef PTIMER_POSIX
+  /* POSIX timers give us a way to measure granularity. */
+  assert (posix_resolution != 0);
+  return posix_resolution;
+#endif
+
+#ifdef PTIMER_GETTIMEOFDAY
+  /* Granularity of gettimeofday varies wildly between architectures.
+     However, it appears that on modern machines it tends to be better
+     than 1ms.  Assume 100 usecs.  */
+  return 0.1;
+#endif
+
+#ifdef PTIMER_TIME
+  return 1000;
+#endif
+
+#ifdef PTIMER_WINDOWS
+  if (windows_hires_timers)
+    return 1.0 / windows_hires_msfreq;
+  else
+    return 10;  /* according to MSDN */
+#endif
+}
diff --git a/src/ptimer.h b/src/ptimer.h
new file mode 100644 (file)
index 0000000..244c183
--- /dev/null
@@ -0,0 +1,46 @@
+/* Declarations for ptimer.c.
+   Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Wget.
+
+GNU Wget is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+GNU Wget is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Wget; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+In addition, as a special exception, the Free Software Foundation
+gives permission to link the code of its release of Wget with the
+OpenSSL project's "OpenSSL" library (or with modified versions of it
+that use the same license as the "OpenSSL" library), and distribute
+the linked executables.  You must obey the GNU General Public License
+in all respects for all of the code used other than "OpenSSL".  If you
+modify this file, you may extend this exception to your version of the
+file, but you are not obligated to do so.  If you do not wish to do
+so, delete this exception statement from your version.  */
+
+#ifndef PTIMER_H
+#define PTIMER_H
+
+struct ptimer;                 /* forward declaration; all struct
+                                   members are private */
+
+struct ptimer *ptimer_allocate PARAMS ((void));
+struct ptimer *ptimer_new PARAMS ((void));
+void ptimer_destroy PARAMS ((struct ptimer *));
+
+void ptimer_reset PARAMS ((struct ptimer *));
+double ptimer_measure PARAMS ((struct ptimer *));
+double ptimer_read PARAMS ((const struct ptimer *));
+
+double ptimer_granularity PARAMS ((void));
+
+#endif /* PTIMER_H */
index a19262a03c1fce7ad30b35341781132f79036431..a5198b7e591171792bf8b11360003d01c8dc4fed 100644 (file)
@@ -54,6 +54,7 @@ so, delete this exception statement from your version.  */
 #include "connect.h"
 #include "hash.h"
 #include "convert.h"
+#include "ptimer.h"
 
 #ifdef HAVE_SSL
 # include "gen_sslfunc.h"      /* for ssl_iread */
@@ -92,9 +93,9 @@ limit_bandwidth_reset (void)
    is the timer that started at the beginning of download.  */
 
 static void
-limit_bandwidth (wgint bytes, struct wget_timer *timer)
+limit_bandwidth (wgint bytes, struct ptimer *timer)
 {
-  double delta_t = wtimer_read (timer) - limit_data.chunk_start;
+  double delta_t = ptimer_read (timer) - limit_data.chunk_start;
   double expected;
 
   limit_data.chunk_bytes += bytes;
@@ -119,10 +120,9 @@ limit_bandwidth (wgint bytes, struct wget_timer *timer)
               slp, number_to_static_string (limit_data.chunk_bytes),
               limit_data.sleep_adjust));
 
-      t0 = wtimer_read (timer);
+      t0 = ptimer_read (timer);
       xsleep (slp / 1000);
-      wtimer_update (timer);
-      t1 = wtimer_read (timer);
+      t1 = ptimer_measure (timer);
 
       /* Due to scheduling, we probably slept slightly longer (or
         shorter) than desired.  Calculate the difference between the
@@ -132,7 +132,7 @@ limit_bandwidth (wgint bytes, struct wget_timer *timer)
     }
 
   limit_data.chunk_bytes = 0;
-  limit_data.chunk_start = wtimer_read (timer);
+  limit_data.chunk_start = ptimer_read (timer);
 }
 
 #ifndef MIN
@@ -202,7 +202,7 @@ fd_read_body (int fd, FILE *out, wgint toread, wgint startpos,
   static char dlbuf[16384];
   int dlbufsize = sizeof (dlbuf);
 
-  struct wget_timer *timer = NULL;
+  struct ptimer *timer = NULL;
   double last_successful_read_tm = 0;
 
   /* The progress gauge, set according to the user preferences. */
@@ -241,7 +241,7 @@ fd_read_body (int fd, FILE *out, wgint toread, wgint startpos,
      the timer.  */
   if (progress || opt.limit_rate || elapsed)
     {
-      timer = wtimer_new ();
+      timer = ptimer_new ();
       last_successful_read_tm = 0;
     }
 
@@ -269,7 +269,7 @@ fd_read_body (int fd, FILE *out, wgint toread, wgint startpos,
          if (opt.read_timeout)
            {
              double waittm;
-             waittm = (wtimer_read (timer) - last_successful_read_tm) / 1000;
+             waittm = (ptimer_read (timer) - last_successful_read_tm) / 1000;
              if (waittm + tmout > opt.read_timeout)
                {
                  /* Don't let total idle time exceed read timeout. */
@@ -292,9 +292,9 @@ fd_read_body (int fd, FILE *out, wgint toread, wgint startpos,
 
       if (progress || opt.limit_rate)
        {
-         wtimer_update (timer);
+         ptimer_measure (timer);
          if (ret > 0)
-           last_successful_read_tm = wtimer_read (timer);
+           last_successful_read_tm = ptimer_read (timer);
        }
 
       if (ret > 0)
@@ -311,7 +311,7 @@ fd_read_body (int fd, FILE *out, wgint toread, wgint startpos,
        limit_bandwidth (ret, timer);
 
       if (progress)
-       progress_update (progress, ret, wtimer_read (timer));
+       progress_update (progress, ret, ptimer_read (timer));
 #ifdef WINDOWS
       if (toread > 0 && !opt.quiet)
        ws_percenttitle (100.0 *
@@ -323,12 +323,12 @@ fd_read_body (int fd, FILE *out, wgint toread, wgint startpos,
 
  out:
   if (progress)
-    progress_finish (progress, wtimer_read (timer));
+    progress_finish (progress, ptimer_read (timer));
 
   if (elapsed)
-    *elapsed = wtimer_read (timer);
+    *elapsed = ptimer_read (timer);
   if (timer)
-    wtimer_delete (timer);
+    ptimer_destroy (timer);
 
   if (qtyread)
     *qtyread += sum_read;
@@ -534,11 +534,12 @@ calc_rate (wgint bytes, double msecs, int *units)
 
   if (msecs == 0)
     /* If elapsed time is exactly zero, it means we're under the
-       granularity of the timer.  This often happens on systems that
-       use time() for the timer.  */
-    msecs = wtimer_granularity ();
+       granularity of the timer.  This can easily happen on systems
+       that use time() for the timer.  Since the interval lies between
+       0 and the timer's granularity, assume half the granularity.  */
+    msecs = ptimer_granularity () / 2.0;
 
-  dlrate = (double)1000 * bytes / msecs;
+  dlrate = 1000.0 * bytes / msecs;
   if (dlrate < 1024.0)
     *units = 0;
   else if (dlrate < 1024.0 * 1024.0)
index 2e45c4d5812edb4966cd83aa9ae98e0c88d6a53c..dc16d55afc5940d095b9ada5d33f4d6d77deb809 100644 (file)
@@ -1515,352 +1515,6 @@ number_to_static_string (wgint number)
   return buf;
 }
 \f
-/* Support for timers. */
-
-#undef TIMER_WINDOWS
-#undef TIMER_GETTIMEOFDAY
-#undef TIMER_TIME
-
-/* Depending on the OS and availability of gettimeofday(), one and
-   only one of the above constants will be defined.  Virtually all
-   modern Unix systems will define TIMER_GETTIMEOFDAY; Windows will
-   use TIMER_WINDOWS.  TIMER_TIME is a catch-all method for
-   non-Windows systems without gettimeofday.  */
-
-#ifdef WINDOWS
-# define TIMER_WINDOWS
-#else  /* not WINDOWS */
-# ifdef HAVE_GETTIMEOFDAY
-#  define TIMER_GETTIMEOFDAY
-# else
-#  define TIMER_TIME
-# endif
-#endif /* not WINDOWS */
-
-#ifdef TIMER_GETTIMEOFDAY
-typedef struct timeval wget_sys_time;
-#endif
-
-#ifdef TIMER_TIME
-typedef time_t wget_sys_time;
-#endif
-
-#ifdef TIMER_WINDOWS
-typedef union {
-  DWORD lores;          /* In case GetTickCount is used */
-  LARGE_INTEGER hires;  /* In case high-resolution timer is used */
-} wget_sys_time;
-#endif
-
-struct wget_timer {
-  /* Whether the start time has been initialized. */
-  int initialized;
-
-  /* The starting point in time which, subtracted from the current
-     time, yields elapsed time. */
-  wget_sys_time start;
-
-  /* The most recent elapsed time, calculated by wtimer_update().
-     Measured in milliseconds.  */
-  double elapsed_last;
-
-  /* Approximately, the time elapsed between the true start of the
-     measurement and the time represented by START.  */
-  double elapsed_pre_start;
-};
-
-#ifdef TIMER_WINDOWS
-
-/* Whether high-resolution timers are used.  Set by wtimer_initialize_once
-   the first time wtimer_allocate is called. */
-static int using_hires_timers;
-
-/* Frequency of high-resolution timers -- number of updates per
-   millisecond.  Calculated the first time wtimer_allocate is called
-   provided that high-resolution timers are available. */
-static double hires_millisec_freq;
-
-/* The first time a timer is created, determine whether to use
-   high-resolution timers. */
-
-static void
-wtimer_initialize_once (void)
-{
-  static int init_done;
-  if (!init_done)
-    {
-      LARGE_INTEGER freq;
-      init_done = 1;
-      freq.QuadPart = 0;
-      QueryPerformanceFrequency (&freq);
-      if (freq.QuadPart != 0)
-        {
-          using_hires_timers = 1;
-          hires_millisec_freq = (double) freq.QuadPart / 1000.0;
-        }
-     }
-}
-#endif /* TIMER_WINDOWS */
-
-/* Allocate a timer.  Calling wtimer_read on the timer will return
-   zero.  It is not legal to call wtimer_update with a freshly
-   allocated timer -- use wtimer_reset first.  */
-
-struct wget_timer *
-wtimer_allocate (void)
-{
-  struct wget_timer *wt = xnew (struct wget_timer);
-  xzero (*wt);
-
-#ifdef TIMER_WINDOWS
-  wtimer_initialize_once ();
-#endif
-
-  return wt;
-}
-
-/* Allocate a new timer and reset it.  Return the new timer. */
-
-struct wget_timer *
-wtimer_new (void)
-{
-  struct wget_timer *wt = wtimer_allocate ();
-  wtimer_reset (wt);
-  return wt;
-}
-
-/* Free the resources associated with the timer.  Its further use is
-   prohibited.  */
-
-void
-wtimer_delete (struct wget_timer *wt)
-{
-  xfree (wt);
-}
-
-/* Store system time to WST.  */
-
-static void
-wtimer_sys_set (wget_sys_time *wst)
-{
-#ifdef TIMER_GETTIMEOFDAY
-  gettimeofday (wst, NULL);
-#endif
-
-#ifdef TIMER_TIME
-  time (wst);
-#endif
-
-#ifdef TIMER_WINDOWS
-  if (using_hires_timers)
-    {
-      QueryPerformanceCounter (&wst->hires);
-    }
-  else
-    {
-      /* Where hires counters are not available, use GetTickCount rather
-         GetSystemTime, because it is unaffected by clock skew and simpler
-         to use.  Note that overflows don't affect us because we never use
-         absolute values of the ticker, only the differences.  */
-      wst->lores = GetTickCount ();
-    }
-#endif
-}
-
-/* Reset timer WT.  This establishes the starting point from which
-   wtimer_read() will return the number of elapsed milliseconds.
-   It is allowed to reset a previously used timer.  */
-
-void
-wtimer_reset (struct wget_timer *wt)
-{
-  /* Set the start time to the current time. */
-  wtimer_sys_set (&wt->start);
-  wt->elapsed_last = 0;
-  wt->elapsed_pre_start = 0;
-  wt->initialized = 1;
-}
-
-static double
-wtimer_sys_diff (wget_sys_time *wst1, wget_sys_time *wst2)
-{
-#ifdef TIMER_GETTIMEOFDAY
-  return ((double)(wst1->tv_sec - wst2->tv_sec) * 1000
-         + (double)(wst1->tv_usec - wst2->tv_usec) / 1000);
-#endif
-
-#ifdef TIMER_TIME
-  return 1000 * (*wst1 - *wst2);
-#endif
-
-#ifdef WINDOWS
-  if (using_hires_timers)
-    return (wst1->hires.QuadPart - wst2->hires.QuadPart) / hires_millisec_freq;
-  else
-    return wst1->lores - wst2->lores;
-#endif
-}
-
-/* Update the timer's elapsed interval.  This function causes the
-   timer to call gettimeofday (or time(), etc.) to update its idea of
-   current time.  To get the elapsed interval in milliseconds, use
-   wtimer_read.
-
-   This function handles clock skew, i.e. time that moves backwards is
-   ignored.  */
-
-void
-wtimer_update (struct wget_timer *wt)
-{
-  wget_sys_time now;
-  double elapsed;
-
-  assert (wt->initialized != 0);
-
-  wtimer_sys_set (&now);
-  elapsed = wt->elapsed_pre_start + wtimer_sys_diff (&now, &wt->start);
-
-  /* Ideally we'd just return the difference between NOW and
-     wt->start.  However, the system timer can be set back, and we
-     could return a value smaller than when we were last called, even
-     a negative value.  Both of these would confuse the callers, which
-     expect us to return monotonically nondecreasing values.
-
-     Therefore: if ELAPSED is smaller than its previous known value,
-     we reset wt->start to the current time and effectively start
-     measuring from this point.  But since we don't want the elapsed
-     value to start from zero, we set elapsed_pre_start to the last
-     elapsed time and increment all future calculations by that
-     amount.  */
-
-  if (elapsed < wt->elapsed_last)
-    {
-      wt->start = now;
-      wt->elapsed_pre_start = wt->elapsed_last;
-      elapsed = wt->elapsed_last;
-    }
-
-  wt->elapsed_last = elapsed;
-}
-
-/* Return the elapsed time in milliseconds between the last call to
-   wtimer_reset and the last call to wtimer_update.
-
-   A typical use of the timer interface would be:
-
-       struct wtimer *timer = wtimer_new ();
-       ... do something that takes a while ...
-       wtimer_update ();
-       double msecs = wtimer_read ();  */
-
-double
-wtimer_read (const struct wget_timer *wt)
-{
-  return wt->elapsed_last;
-}
-
-/* Return the assessed granularity of the timer implementation, in
-   milliseconds.  This is used by code that tries to substitute a
-   better value for timers that have returned zero.  */
-
-double
-wtimer_granularity (void)
-{
-#ifdef TIMER_GETTIMEOFDAY
-  /* Granularity of gettimeofday varies wildly between architectures.
-     However, it appears that on modern machines it tends to be better
-     than 1ms.  Assume 100 usecs.  (Perhaps the configure process
-     could actually measure this?)  */
-  return 0.1;
-#endif
-
-#ifdef TIMER_TIME
-  return 1000;
-#endif
-
-#ifdef TIMER_WINDOWS
-  if (using_hires_timers)
-    return 1.0 / hires_millisec_freq;
-  else
-    return 10;  /* according to MSDN */
-#endif
-}
-\f
-/* This should probably be at a better place, but it doesn't really
-   fit into html-parse.c.  */
-
-/* The function returns the pointer to the malloc-ed quoted version of
-   string s.  It will recognize and quote numeric and special graphic
-   entities, as per RFC1866:
-
-   `&' -> `&amp;'
-   `<' -> `&lt;'
-   `>' -> `&gt;'
-   `"' -> `&quot;'
-   SP  -> `&#32;'
-
-   No other entities are recognized or replaced.  */
-char *
-html_quote_string (const char *s)
-{
-  const char *b = s;
-  char *p, *res;
-  int i;
-
-  /* Pass through the string, and count the new size.  */
-  for (i = 0; *s; s++, i++)
-    {
-      if (*s == '&')
-       i += 4;                 /* `amp;' */
-      else if (*s == '<' || *s == '>')
-       i += 3;                 /* `lt;' and `gt;' */
-      else if (*s == '\"')
-       i += 5;                 /* `quot;' */
-      else if (*s == ' ')
-       i += 4;                 /* #32; */
-    }
-  res = (char *)xmalloc (i + 1);
-  s = b;
-  for (p = res; *s; s++)
-    {
-      switch (*s)
-       {
-       case '&':
-         *p++ = '&';
-         *p++ = 'a';
-         *p++ = 'm';
-         *p++ = 'p';
-         *p++ = ';';
-         break;
-       case '<': case '>':
-         *p++ = '&';
-         *p++ = (*s == '<' ? 'l' : 'g');
-         *p++ = 't';
-         *p++ = ';';
-         break;
-       case '\"':
-         *p++ = '&';
-         *p++ = 'q';
-         *p++ = 'u';
-         *p++ = 'o';
-         *p++ = 't';
-         *p++ = ';';
-         break;
-       case ' ':
-         *p++ = '&';
-         *p++ = '#';
-         *p++ = '3';
-         *p++ = '2';
-         *p++ = ';';
-         break;
-       default:
-         *p++ = *s;
-       }
-    }
-  *p = '\0';
-  return res;
-}
-
 /* Determine the width of the terminal we're running on.  If that's
    not possible, return 0.  */
 
@@ -2284,7 +1938,7 @@ base64_decode (const char *base64, char *to)
        {
          NEXT_BASE64_CHAR (c, p);
          if (!c)
-           return -1;          /* premature EOF while dcoding base64 */
+           return -1;          /* premature EOF while decoding base64 */
          if (c != '=')
            return -1;          /* padding `=' expected but not found */
          continue;
@@ -2296,7 +1950,7 @@ base64_decode (const char *base64, char *to)
       /* Process fourth byte of a quadruplet.  */
       NEXT_BASE64_CHAR (c, p);
       if (!c)
-       return -1;              /* premature EOF while dcoding base64 */
+       return -1;              /* premature EOF while decoding base64 */
       if (c == '=')
        continue;
 
index 119cd281e104b8101dad5671dbd8b1da722c2062..afef13c9402f2d105110fe1aa7959b944d841531 100644 (file)
@@ -44,8 +44,6 @@ struct file_memory {
 
 #define HYPHENP(x) (*(x) == '-' && !*((x) + 1))
 
-struct wget_timer;
-
 char *time_str PARAMS ((time_t *));
 char *datetime_str PARAMS ((time_t *));
 
@@ -108,16 +106,6 @@ int numdigit PARAMS ((wgint));
 char *number_to_string PARAMS ((char *, wgint));
 char *number_to_static_string PARAMS ((wgint));
 
-struct wget_timer *wtimer_allocate PARAMS ((void));
-struct wget_timer *wtimer_new PARAMS ((void));
-void wtimer_delete PARAMS ((struct wget_timer *));
-void wtimer_reset PARAMS ((struct wget_timer *));
-void wtimer_update PARAMS ((struct wget_timer *));
-double wtimer_read PARAMS ((const struct wget_timer *));
-double wtimer_granularity PARAMS ((void));
-
-char *html_quote_string PARAMS ((const char *));
-
 int determine_screen_width PARAMS ((void));
 int random_number PARAMS ((int));
 double random_float PARAMS ((void));