From 5dd7e031675d21c2ab28d464d64422ee1f097341 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 17 May 1998 05:56:32 +0000 Subject: [PATCH] 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 --- io.c | 117 +++++++++++++++++++++++++++++--------------------------- rsync.h | 1 + 2 files changed, 62 insertions(+), 56 deletions(-) diff --git a/io.c b/io.c index ccb099a9..80d0858f 100644 --- a/io.c +++ b/io.c @@ -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; } } diff --git a/rsync.h b/rsync.h index 187ef375..1a691586 100644 --- a/rsync.h +++ b/rsync.h @@ -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 -- 2.34.1