Commit 5dd7e031 authored by Andrew Tridgell's avatar Andrew Tridgell

put a limit (default 1MB) on the read buffer size. This stops it

growing too much if the sender is much faster than the receiver
parent 08ac228f
......@@ -61,39 +61,42 @@ static int read_buffer_size;
* ssh will clag up. Uggh. */
static void read_check(int f)
{
int n;
int n;
if (f == -1) return;
if (f == -1) return;
if (read_buffer_len == 0) {
read_buffer_p = read_buffer;
}
if (read_buffer_len == 0) {
read_buffer_p = read_buffer;
}
if ((n=num_waiting(f)) <= 0)
return;
if ((n=num_waiting(f)) <= 0)
return;
/* things could deteriorate if we read in really small chunks */
if (n < 10) n = 1024;
/* things could deteriorate if we read in really small chunks */
if (n < 10) n = 1024;
if (read_buffer_p != read_buffer) {
memmove(read_buffer,read_buffer_p,read_buffer_len);
read_buffer_p = read_buffer;
}
if (n > MAX_READ_BUFFER/4)
n = MAX_READ_BUFFER/4;
if (n > (read_buffer_size - read_buffer_len)) {
read_buffer_size += n;
if (!read_buffer)
read_buffer = (char *)malloc(read_buffer_size);
else
read_buffer = (char *)realloc(read_buffer,read_buffer_size);
if (!read_buffer) out_of_memory("read check");
read_buffer_p = read_buffer;
}
if (read_buffer_p != read_buffer) {
memmove(read_buffer,read_buffer_p,read_buffer_len);
read_buffer_p = read_buffer;
}
n = read(f,read_buffer+read_buffer_len,n);
if (n > 0) {
read_buffer_len += n;
}
if (n > (read_buffer_size - read_buffer_len)) {
read_buffer_size += n;
if (!read_buffer)
read_buffer = (char *)malloc(read_buffer_size);
else
read_buffer = (char *)realloc(read_buffer,read_buffer_size);
if (!read_buffer) out_of_memory("read check");
read_buffer_p = read_buffer;
}
n = read(f,read_buffer+read_buffer_len,n);
if (n > 0) {
read_buffer_len += n;
}
}
static time_t last_io;
......@@ -334,38 +337,40 @@ static int writefd_unbuffered(int fd,char *buf,int len)
if (ret == -1) {
read_check(buffer_f_in);
fd_count = fd+1;
FD_ZERO(&w_fds);
FD_ZERO(&r_fds);
FD_SET(fd,&w_fds);
if (buffer_f_in != -1) {
FD_SET(buffer_f_in,&r_fds);
if (buffer_f_in > fd)
fd_count = buffer_f_in+1;
}
tv.tv_sec = BLOCKING_TIMEOUT;
tv.tv_usec = 0;
count = select(fd_count,buffer_f_in == -1? NULL: &r_fds,
&w_fds,NULL,&tv);
if (count == -1 && errno != EINTR) {
if (verbose > 1)
rprintf(FERROR,"select error: %s\n", strerror(errno));
exit_cleanup(1);
}
if (count == 0) {
check_timeout();
continue;
}
if (read_buffer_len < MAX_READ_BUFFER)
read_check(buffer_f_in);
fd_count = fd+1;
FD_ZERO(&w_fds);
FD_ZERO(&r_fds);
FD_SET(fd,&w_fds);
if (buffer_f_in != -1) {
FD_SET(buffer_f_in,&r_fds);
if (buffer_f_in > fd)
fd_count = buffer_f_in+1;
}
tv.tv_sec = BLOCKING_TIMEOUT;
tv.tv_usec = 0;
count = select(fd_count,buffer_f_in == -1? NULL: &r_fds,
&w_fds,NULL,&tv);
if (count == -1 && errno != EINTR) {
if (verbose > 1)
rprintf(FERROR,"select error: %s\n", strerror(errno));
exit_cleanup(1);
}
if (count == 0) {
check_timeout();
continue;
}
if (FD_ISSET(fd, &w_fds)) {
got_select = 1;
}
if (FD_ISSET(fd, &w_fds)) {
got_select = 1;
}
} else {
total += ret;
total += ret;
}
}
......
......@@ -52,6 +52,7 @@
#define CHUNK_SIZE (32*1024)
#define MAX_MAP_SIZE (4*1024*1024)
#define IO_BUFFER_SIZE (4096)
#define MAX_READ_BUFFER (1024*1024)
#define MAX_ARGS 1000
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment