I think I've (finally) fixed the problem with rsync periodically
authorAndrew Tridgell <tridge@samba.org>
Mon, 15 Dec 1997 12:33:15 +0000 (12:33 +0000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 15 Dec 1997 12:33:15 +0000 (12:33 +0000)
freezing when used with ssh. The problem is really the ssh use of
blocking calls. rsync has had a fix for this for a while which relies
on using non-blocking calls itself and then reading any data from the
incoming fd when trying to write, thus ensuring that the incoming fd
doesn't get full.
The problem was the the incoming fd wasn't added to the select
statement, which meant that new data arriving on the fd only got read
when the select timed out, which happens every 10 seconds. Thus things
could slow to a crawl!
The incoming fd is now in the select call, and this seems to fix the
problem.

io.c

diff --git a/io.c b/io.c
index e7292df..51fc0cb 100644 (file)
--- a/io.c
+++ b/io.c
@@ -62,6 +62,8 @@ static void read_check(int f)
 {
   int n;
 
+  if (f == -1) return;
+
   if (read_buffer_len == 0) {
     read_buffer_p = read_buffer;
   }
@@ -69,6 +71,9 @@ static void read_check(int f)
   if ((n=num_waiting(f)) <= 0)
     return;
 
+  /* 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;
@@ -95,10 +100,13 @@ static int readfd(int fd,char *buffer,int N)
 {
   int  ret;
   int total=0;  
+
+  if (read_buffer_len < N)
+         read_check(buffer_f_in);
  
   while (total < N)
     {
-      if (read_buffer_len > 0) {
+      if (read_buffer_len > 0 && buffer_f_in == fd) {
        ret = MIN(read_buffer_len,N-total);
        memcpy(buffer+total,read_buffer_p,ret);
        read_buffer_p += ret;
@@ -228,7 +236,8 @@ int read_write(int fd_in,int fd_out,int size)
 static int writefd(int fd,char *buf,int len)
 {
   int total = 0;
-  fd_set fds;
+  fd_set w_fds, r_fds;
+  int fd_count;
   struct timeval tv;
 
   if (buffer_f_in == -1) 
@@ -245,11 +254,18 @@ static int writefd(int fd,char *buf,int len)
     if (ret == -1) {
       read_check(buffer_f_in);
 
-      FD_ZERO(&fds);
-      FD_SET(fd,&fds);
+      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;
-      select(fd+1,NULL,&fds,NULL,&tv);
+      select(fd_count,buffer_f_in == -1? NULL: &r_fds,&w_fds,NULL,&tv);
     } else {
       total += ret;
     }