X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/a800434a82af8dbd59da7c27b382c9897dd90150..c95da96a0c51c66c8cb2eff97b768a717d9e0c79:/io.c diff --git a/io.c b/io.c index 61bdc609..d7140d26 100644 --- a/io.c +++ b/io.c @@ -108,6 +108,15 @@ static int read_timeout(int fd, char *buf, int len) continue; } + if (n == -1 && + (errno == EAGAIN || errno == EWOULDBLOCK)) { + /* this shouldn't happen, if it does then + sleep for a short time to prevent us + chewing too much CPU */ + u_sleep(100); + continue; + } + if (n == 0) { if (eof_error) { rprintf(FERROR,"EOF in read_timeout\n"); @@ -310,6 +319,7 @@ static void writefd_unbuffered(int fd,char *buf,int len) int fd_count, count; struct timeval tv; int reading; + int blocked=0; no_flush++; @@ -341,17 +351,25 @@ static void writefd_unbuffered(int fd,char *buf,int len) } if (FD_ISSET(fd, &w_fds)) { - int ret = write(fd,buf+total,len-total); + int n = (len-total)>>blocked; + int ret = write(fd,buf+total,n?n:1); if (ret == -1 && errno == EINTR) { continue; } + if (ret == -1 && + (errno == EAGAIN || errno == EWOULDBLOCK)) { + blocked++; + continue; + } + if (ret <= 0) { rprintf(FERROR,"erroring writing %d bytes - exiting\n", len); exit_cleanup(1); } + blocked = 0; total += ret; stats.total_written += ret;