put a limit (default 1MB) on the read buffer size. This stops it
authorAndrew Tridgell <tridge@samba.org>
Sun, 17 May 1998 05:56:32 +0000 (05:56 +0000)
committerAndrew Tridgell <tridge@samba.org>
Sun, 17 May 1998 05:56:32 +0000 (05:56 +0000)
growing too much if the sender is much faster than the receiver

io.c
rsync.h

diff --git a/io.c b/io.c
index ccb099a..80d0858 100644 (file)
--- 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 187ef37..1a69158 100644 (file)
--- 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