diff --git a/src/ChangeLog b/src/ChangeLog index b3a321fe..4b7b79e4 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2003-09-15 Hrvoje Niksic + + * retr.c (get_contents): Reduce the buffer size to the amount of + data that may pass through for one second. This prevents long + sleeps when limiting bandwidth. + + * connect.c (connect_to_one): Reduce the socket's RCVBUF when + bandwidth limitation to small values is requested. + 2003-09-15 Hrvoje Niksic * progress.c (update_speed_ring): Moved the speed ring update to a diff --git a/src/connect.c b/src/connect.c index 26dc404d..7ac7d3fb 100644 --- a/src/connect.c +++ b/src/connect.c @@ -176,6 +176,20 @@ connect_to_one (ip_address *addr, unsigned short port, int silent) if (sock < 0) goto out; +#ifdef SO_RCVBUF + /* For very small rate limits, set the buffer size (and hence, + hopefully, the size of the kernel window) to the size of the + limit. */ + if (opt.limit_rate && opt.limit_rate < 8192) + { + int bufsize = opt.limit_rate; + if (bufsize < 512) + bufsize = 512; + setsockopt (sock, SOL_SOCKET, SO_RCVBUF, + (char *)&bufsize, sizeof (bufsize)); + } +#endif + resolve_bind_address (); if (bind_address_resolved) { @@ -292,9 +306,12 @@ bindport (unsigned short *port, int family) if ((msock = socket (family, SOCK_STREAM, 0)) < 0) return CONSOCKERR; + +#ifdef SO_REUSEADDR if (setsockopt (msock, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof (optval)) < 0) return CONSOCKERR; +#endif resolve_bind_address (); wget_sockaddr_set_address (&srv, ip_default_family, htons (*port), diff --git a/src/retr.c b/src/retr.c index e619f1cb..4328aad6 100644 --- a/src/retr.c +++ b/src/retr.c @@ -138,7 +138,10 @@ get_contents (int fd, FILE *fp, long *len, long restval, long expected, 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; @@ -151,9 +154,9 @@ get_contents (int fd, FILE *fp, long *len, long restval, long expected, 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; } @@ -172,6 +175,11 @@ get_contents (int fd, FILE *fp, long *len, long restval, long expected, 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 @@ -180,18 +188,17 @@ get_contents (int fd, FILE *fp, long *len, long restval, long expected, 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, dlbufsize, amount_to_read); else #endif /* HAVE_SSL */ - res = iread (fd, c, amount_to_read); + res = iread (fd, dlbuf, amount_to_read); if (res > 0) { - fwrite (c, sizeof (char), res, fp); + fwrite (dlbuf, 1, 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. */