mirror of
https://github.com/moparisthebest/wget
synced 2024-07-03 16:38:41 -04:00
[svn] Fixed a long-standing bug in the timer code that would cause Wget to
crash when the system time was set back during a Wget run. Message-ID: <m3znh8wag9.fsf@hniksic.iskon.hr>
This commit is contained in:
parent
7e7ce3dc0e
commit
ebea9e7e0b
@ -1,3 +1,17 @@
|
|||||||
|
2003-09-14 Hrvoje Niksic <hniksic@xemacs.org>
|
||||||
|
|
||||||
|
* utils.c (wtimer_sys_set): Extracted the code that sets the
|
||||||
|
current time here.
|
||||||
|
(wtimer_reset): Call it.
|
||||||
|
(wtimer_sys_diff): Extracted the code that calculates the
|
||||||
|
difference between two system times here.
|
||||||
|
(wtimer_elapsed): Call it.
|
||||||
|
(wtimer_elapsed): Don't return a value smaller than the previous
|
||||||
|
one, which could previously happen when system time is set back.
|
||||||
|
Instead, reset start time to current time and note the elapsed
|
||||||
|
offset for future calculations. The returned times are now
|
||||||
|
guaranteed to be monotonically nondecreasing.
|
||||||
|
|
||||||
2003-09-10 Hrvoje Niksic <hniksic@xemacs.org>
|
2003-09-10 Hrvoje Niksic <hniksic@xemacs.org>
|
||||||
|
|
||||||
* host.c (lookup_host): Print the result of the DNS lookup.
|
* host.c (lookup_host): Print the result of the DNS lookup.
|
||||||
|
115
src/utils.c
115
src/utils.c
@ -1532,19 +1532,30 @@ number_to_string (char *buffer, long number)
|
|||||||
# endif
|
# endif
|
||||||
#endif /* not WINDOWS */
|
#endif /* not WINDOWS */
|
||||||
|
|
||||||
struct wget_timer {
|
|
||||||
#ifdef TIMER_GETTIMEOFDAY
|
#ifdef TIMER_GETTIMEOFDAY
|
||||||
long secs;
|
typedef struct timeval wget_sys_time;
|
||||||
long usecs;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TIMER_TIME
|
#ifdef TIMER_TIME
|
||||||
time_t secs;
|
typedef time_t wget_sys_time;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TIMER_WINDOWS
|
#ifdef TIMER_WINDOWS
|
||||||
ULARGE_INTEGER wintime;
|
typedef ULARGE_INTEGER wget_sys_time;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct wget_timer {
|
||||||
|
/* 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_elapsed().
|
||||||
|
Measured in milliseconds. */
|
||||||
|
long elapsed_last;
|
||||||
|
|
||||||
|
/* Approximately, the time elapsed between the true start of the
|
||||||
|
measurement and the time represented by START. */
|
||||||
|
long elapsed_pre_start;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Allocate a timer. It is not legal to do anything with a freshly
|
/* Allocate a timer. It is not legal to do anything with a freshly
|
||||||
@ -1577,22 +1588,17 @@ wtimer_delete (struct wget_timer *wt)
|
|||||||
xfree (wt);
|
xfree (wt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset timer WT. This establishes the starting point from which
|
/* Store system time to WST. */
|
||||||
wtimer_elapsed() will return the number of elapsed
|
|
||||||
milliseconds. It is allowed to reset a previously used timer. */
|
|
||||||
|
|
||||||
void
|
static void
|
||||||
wtimer_reset (struct wget_timer *wt)
|
wtimer_sys_set (wget_sys_time *wst)
|
||||||
{
|
{
|
||||||
#ifdef TIMER_GETTIMEOFDAY
|
#ifdef TIMER_GETTIMEOFDAY
|
||||||
struct timeval t;
|
gettimeofday (wst, NULL);
|
||||||
gettimeofday (&t, NULL);
|
|
||||||
wt->secs = t.tv_sec;
|
|
||||||
wt->usecs = t.tv_usec;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TIMER_TIME
|
#ifdef TIMER_TIME
|
||||||
wt->secs = time (NULL);
|
time (wst);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TIMER_WINDOWS
|
#ifdef TIMER_WINDOWS
|
||||||
@ -1600,8 +1606,38 @@ wtimer_reset (struct wget_timer *wt)
|
|||||||
SYSTEMTIME st;
|
SYSTEMTIME st;
|
||||||
GetSystemTime (&st);
|
GetSystemTime (&st);
|
||||||
SystemTimeToFileTime (&st, &ft);
|
SystemTimeToFileTime (&st, &ft);
|
||||||
wt->wintime.HighPart = ft.dwHighDateTime;
|
wst->HighPart = ft.dwHighDateTime;
|
||||||
wt->wintime.LowPart = ft.dwLowDateTime;
|
wst->LowPart = ft.dwLowDateTime;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset timer WT. This establishes the starting point from which
|
||||||
|
wtimer_elapsed() 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long
|
||||||
|
wtimer_sys_diff (wget_sys_time *wst1, wget_sys_time *wst2)
|
||||||
|
{
|
||||||
|
#ifdef TIMER_GETTIMEOFDAY
|
||||||
|
return ((wst1->tv_sec - wst2->tv_sec) * 1000
|
||||||
|
+ (wst1->tv_usec - wst2->tv_usec) / 1000);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TIMER_TIME
|
||||||
|
return 1000 * (*wst1 - *wst2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
return (long)(wst1->QuadPart - wst2->QuadPart) / 10000;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1612,27 +1648,34 @@ wtimer_reset (struct wget_timer *wt)
|
|||||||
long
|
long
|
||||||
wtimer_elapsed (struct wget_timer *wt)
|
wtimer_elapsed (struct wget_timer *wt)
|
||||||
{
|
{
|
||||||
#ifdef TIMER_GETTIMEOFDAY
|
wget_sys_time now;
|
||||||
struct timeval t;
|
long elapsed;
|
||||||
gettimeofday (&t, NULL);
|
|
||||||
return (t.tv_sec - wt->secs) * 1000 + (t.tv_usec - wt->usecs) / 1000;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef TIMER_TIME
|
wtimer_sys_set (&now);
|
||||||
time_t now = time (NULL);
|
elapsed = wt->elapsed_pre_start + wtimer_sys_diff (&now, &wt->start);
|
||||||
return 1000 * (now - wt->secs);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WINDOWS
|
/* Ideally we'd just return the difference between NOW and
|
||||||
FILETIME ft;
|
wt->start. However, the system timer can be set back, and we
|
||||||
SYSTEMTIME st;
|
could return a value smaller than when we were last called, even
|
||||||
ULARGE_INTEGER uli;
|
a negative value. Both of these would confuse the callers, which
|
||||||
GetSystemTime (&st);
|
expect us to return monotonically nondecreasing values.
|
||||||
SystemTimeToFileTime (&st, &ft);
|
|
||||||
uli.HighPart = ft.dwHighDateTime;
|
Therefore: if ELAPSED is smaller than its previous known value,
|
||||||
uli.LowPart = ft.dwLowDateTime;
|
we reset wt->start to the current time and effectively start
|
||||||
return (long)((uli.QuadPart - wt->wintime.QuadPart) / 10000);
|
measuring from this point. But since we don't want the elapsed
|
||||||
#endif
|
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 elapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the assessed granularity of the timer implementation. This
|
/* Return the assessed granularity of the timer implementation. This
|
||||||
|
Loading…
Reference in New Issue
Block a user