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; ...@@ -61,39 +61,42 @@ static int read_buffer_size;
* ssh will clag up. Uggh. */ * ssh will clag up. Uggh. */
static void read_check(int f) static void read_check(int f)
{ {
int n; int n;
if (f == -1) return; if (f == -1) return;
if (read_buffer_len == 0) { if (read_buffer_len == 0) {
read_buffer_p = read_buffer; read_buffer_p = read_buffer;
} }
if ((n=num_waiting(f)) <= 0) if ((n=num_waiting(f)) <= 0)
return; return;
/* things could deteriorate if we read in really small chunks */ /* things could deteriorate if we read in really small chunks */
if (n < 10) n = 1024; if (n < 10) n = 1024;
if (read_buffer_p != read_buffer) { if (n > MAX_READ_BUFFER/4)
memmove(read_buffer,read_buffer_p,read_buffer_len); n = MAX_READ_BUFFER/4;
read_buffer_p = read_buffer;
}
if (n > (read_buffer_size - read_buffer_len)) { if (read_buffer_p != read_buffer) {
read_buffer_size += n; memmove(read_buffer,read_buffer_p,read_buffer_len);
if (!read_buffer) read_buffer_p = 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 > (read_buffer_size - read_buffer_len)) {
if (n > 0) { read_buffer_size += n;
read_buffer_len += 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; static time_t last_io;
...@@ -334,38 +337,40 @@ static int writefd_unbuffered(int fd,char *buf,int len) ...@@ -334,38 +337,40 @@ static int writefd_unbuffered(int fd,char *buf,int len)
if (ret == -1) { if (ret == -1) {
read_check(buffer_f_in); if (read_buffer_len < MAX_READ_BUFFER)
read_check(buffer_f_in);
fd_count = fd+1;
FD_ZERO(&w_fds); fd_count = fd+1;
FD_ZERO(&r_fds); FD_ZERO(&w_fds);
FD_SET(fd,&w_fds); FD_ZERO(&r_fds);
if (buffer_f_in != -1) { FD_SET(fd,&w_fds);
FD_SET(buffer_f_in,&r_fds); if (buffer_f_in != -1) {
if (buffer_f_in > fd) FD_SET(buffer_f_in,&r_fds);
fd_count = buffer_f_in+1; if (buffer_f_in > fd)
} fd_count = buffer_f_in+1;
}
tv.tv_sec = BLOCKING_TIMEOUT;
tv.tv_usec = 0; tv.tv_sec = BLOCKING_TIMEOUT;
count = select(fd_count,buffer_f_in == -1? NULL: &r_fds, tv.tv_usec = 0;
&w_fds,NULL,&tv); count = select(fd_count,buffer_f_in == -1? NULL: &r_fds,
if (count == -1 && errno != EINTR) { &w_fds,NULL,&tv);
if (verbose > 1)
rprintf(FERROR,"select error: %s\n", strerror(errno)); if (count == -1 && errno != EINTR) {
exit_cleanup(1); if (verbose > 1)
} rprintf(FERROR,"select error: %s\n", strerror(errno));
exit_cleanup(1);
if (count == 0) { }
check_timeout();
continue; if (count == 0) {
} check_timeout();
continue;
}
if (FD_ISSET(fd, &w_fds)) { if (FD_ISSET(fd, &w_fds)) {
got_select = 1; got_select = 1;
} }
} else { } else {
total += ret; total += ret;
} }
} }
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#define CHUNK_SIZE (32*1024) #define CHUNK_SIZE (32*1024)
#define MAX_MAP_SIZE (4*1024*1024) #define MAX_MAP_SIZE (4*1024*1024)
#define IO_BUFFER_SIZE (4096) #define IO_BUFFER_SIZE (4096)
#define MAX_READ_BUFFER (1024*1024)
#define MAX_ARGS 1000 #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