}
/* Limit the bandwidth by pausing the download for an amount of time.
- BYTES is the number of bytes received from the network, DELTA is
- how long it took to receive them, DLTIME the current download time,
- TIMER the timer, and ADJUSTMENT the previous. */
+ BYTES is the number of bytes received from the network, and DELTA
+ is the number of milliseconds it took to receive them. */
static void
limit_bandwidth (long bytes, double delta)
struct rbuf *rbuf, int use_expected, double *elapsed)
{
int res = 0;
- static char c[16384];
+
+ static char dlbuf[16384];
+ int dlbufsize = sizeof (dlbuf);
+
void *progress = NULL;
struct wget_timer *timer = wtimer_allocate ();
double dltime = 0, last_dltime = 0;
if (rbuf && RBUF_FD (rbuf) == fd)
{
int sz = 0;
- while ((res = rbuf_flush (rbuf, c, sizeof (c))) != 0)
+ while ((res = rbuf_flush (rbuf, dlbuf, sizeof (dlbuf))) != 0)
{
- fwrite (c, sizeof (char), res, fp);
+ fwrite (dlbuf, 1, res, fp);
*len += res;
sz += res;
}
limit_bandwidth_reset ();
wtimer_reset (timer);
+ /* If we're limiting the download, set our buffer size to the
+ limit. */
+ if (opt.limit_rate && opt.limit_rate < dlbufsize)
+ dlbufsize = opt.limit_rate;
+
/* Read from fd while there is available data.
Normally, if expected is 0, it means that it is not known how
while (!use_expected || (*len < expected))
{
int amount_to_read = (use_expected
- ? MIN (expected - *len, sizeof (c))
- : sizeof (c));
+ ? MIN (expected - *len, dlbufsize) : dlbufsize);
#ifdef HAVE_SSL
if (rbuf->ssl!=NULL)
- res = ssl_iread (rbuf->ssl, c, amount_to_read);
+ res = ssl_iread (rbuf->ssl, dlbuf, amount_to_read);
else
#endif /* HAVE_SSL */
- res = iread (fd, c, amount_to_read);
+ res = iread (fd, dlbuf, amount_to_read);
+
+ if (res <= 0)
+ break;
+
+ fwrite (dlbuf, 1, res, fp);
+ /* Always flush the contents of the network packet. This should
+ not hinder performance: fast downloads will be received in
+ 16K chunks (which stdio would write out anyway), and slow
+ downloads won't be limited with disk performance. */
+ fflush (fp);
+ if (ferror (fp))
+ {
+ res = -2;
+ goto out;
+ }
- if (res > 0)
+ /* If bandwidth is not limited, one call to wtimer_elapsed is
+ sufficient. */
+ dltime = wtimer_elapsed (timer);
+ if (opt.limit_rate)
{
- fwrite (c, sizeof (char), res, fp);
- /* Always flush the contents of the network packet. This
- should not be adverse to performance, as the network
- packets typically won't be too tiny anyway. */
- fflush (fp);
- if (ferror (fp))
- {
- res = -2;
- goto out;
- }
-
- /* If bandwidth is not limited, one call to wtimer_elapsed
- is sufficient. */
+ limit_bandwidth (res, dltime - last_dltime);
dltime = wtimer_elapsed (timer);
- if (opt.limit_rate)
- {
- limit_bandwidth (res, dltime - last_dltime);
- dltime = wtimer_elapsed (timer);
- last_dltime = dltime;
- }
-
- if (progress)
- progress_update (progress, res, dltime);
- *len += res;
+ last_dltime = dltime;
}
- else
- break;
+
+ if (progress)
+ progress_update (progress, res, dltime);
+ *len += res;
}
if (res < -1)
res = -1;
else if (dlrate < 1024.0 * 1024.0 * 1024.0)
*units = 2, dlrate /= (1024.0 * 1024.0);
else
- /* Maybe someone will need this one day. More realistically, it
- will get tickled by buggy timers. */
+ /* Maybe someone will need this, one day. */
*units = 3, dlrate /= (1024.0 * 1024.0 * 1024.0);
return dlrate;
if (count <= opt.waitretry)
sleep (count - 1);
else
- sleep (opt.waitretry);
+ usleep (1000000L * opt.waitretry);
}
else if (opt.wait)
{
/* If random-wait is not specified, or if we are sleeping
between retries of the same download, sleep the fixed
interval. */
- sleep (opt.wait);
+ usleep (1000000L * opt.wait);
else
{
/* Sleep a random amount of time averaging in opt.wait
seconds. The sleeping amount ranges from 0 to
opt.wait*2, inclusive. */
- int waitsecs = random_number (opt.wait * 2 + 1);
-
- DEBUGP (("sleep_between_retrievals: norm=%ld,fuzz=%ld,sleep=%d\n",
- opt.wait, waitsecs - opt.wait, waitsecs));
-
- if (waitsecs)
- sleep (waitsecs);
+ double waitsecs = 2 * opt.wait * random_float ();
+ DEBUGP (("sleep_between_retrievals: avg=%f,sleep=%f\n",
+ opt.wait, waitsecs));
+ usleep (1000000L * waitsecs);
}
}
}