On 7 December 2013 05:32, Andrew Gregory <[email protected]> wrote: > Previously, if the system time was adjusted backwards during a progress > display, get_update_timediff return negative values prevent the progress > bar from updating. Instead, on negative values, the saved time is > reset. Additionally, the download callback ignores the amount > downloaded to avoid skewing the rate.
Have you considered using clock_gettime(CLOCK_MONOTONIC) rather than gettimeofday()? Or is it not available on some platforms? Even if you have to use a different function for OS X or something it mightn’t be much worse than these backwards time hacks. > Fixes FS#36983 > > Signed-off-by: Andrew Gregory <[email protected]> > --- > src/pacman/callback.c | 33 +++++++++++++++++++-------------- > 1 file changed, 19 insertions(+), 14 deletions(-) > > diff --git a/src/pacman/callback.c b/src/pacman/callback.c > index a181fa5..0ffb2ef 100644 > --- a/src/pacman/callback.c > +++ b/src/pacman/callback.c > @@ -73,8 +73,8 @@ static long get_update_timediff(int first_call) > > retval = (diff_sec * 1000) + (diff_usec / 1000); > > - /* do not update last_time if interval was too short */ > - if(retval >= UPDATE_SPEED_MS) { > + /* update last_time if it is in the future or interval was > long enough */ > + if(retval < 0 || retval >= UPDATE_SPEED_MS) { > last_time = this_time; > } > } > @@ -554,7 +554,7 @@ void cb_dl_progress(const char *filename, off_t > file_xfered, off_t file_total) > { > static double rate_last; > static off_t xfered_last; > - static struct timeval initial_time; > + static long elapsed_time = 0; > int infolen; > int filenamelen; > char *fname, *p; > @@ -616,25 +616,23 @@ void cb_dl_progress(const char *filename, off_t > file_xfered, off_t file_total) > /* set default starting values, ensure we only call this once > * if TotalDownload is enabled */ > if(!totaldownload || (totaldownload && list_xfered == 0)) { > - gettimeofday(&initial_time, NULL); > + elapsed_time = 0; > xfered_last = (off_t)0; > rate_last = 0.0; > get_update_timediff(1); > } > } else if(file_xfered == file_total) { > /* compute final values */ > - struct timeval current_time; > - time_t diff_sec; > - suseconds_t diff_usec; > + timediff = get_update_timediff(0); > > - gettimeofday(¤t_time, NULL); > - diff_sec = current_time.tv_sec - initial_time.tv_sec; > - diff_usec = current_time.tv_usec - initial_time.tv_usec; > - timediff = (diff_sec * 1000) + (diff_usec / 1000); > if(timediff > 0) { > - rate = (double)xfered / (timediff / 1000.0); > + elapsed_time += timediff; > + } > + > + if(elapsed_time > 0) { > + rate = (double)xfered / (elapsed_time / 1000.0); > /* round elapsed time (in ms) to the nearest second */ > - eta_s = (unsigned int)(timediff + 500) / 1000; > + eta_s = (unsigned int)(elapsed_time + 500) / 1000; > } else { > eta_s = 0; > } > @@ -642,10 +640,17 @@ void cb_dl_progress(const char *filename, off_t > file_xfered, off_t file_total) > /* compute current average values */ > timediff = get_update_timediff(0); > > - if(timediff < UPDATE_SPEED_MS) { > + if(timediff < 0) { > + /* we lost a chunk of time due to a clock change, > including the amount > + * xfered during that period in the next update would > skew the rate */ > + xfered_last = xfered; > + return; > + } else if(timediff < UPDATE_SPEED_MS) { > /* return if the calling interval was too short */ > return; > } > + > + elapsed_time += timediff; > rate = (double)(xfered - xfered_last) / (timediff / 1000.0); > /* average rate to reduce jumpiness */ > rate = (rate + 2 * rate_last) / 3; > -- > 1.8.4.2
