X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/a800434a82af8dbd59da7c27b382c9897dd90150..6608462cac742530ed6528bfb5ac7e26f43a31ea:/io.c diff --git a/io.c b/io.c index 61bdc609..fc62e452 100644 --- a/io.c +++ b/io.c @@ -54,8 +54,8 @@ static void check_timeout(void) t = time(NULL); - if (last_io && io_timeout && (t-last_io)>io_timeout) { - rprintf(FERROR,"read timeout after %d second - exiting\n", + if (last_io && io_timeout && (t-last_io) >= io_timeout) { + rprintf(FERROR,"io timeout after %d second - exiting\n", (int)(t-last_io)); exit_cleanup(1); } @@ -108,9 +108,18 @@ 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"); + rprintf(FERROR,"unexpected EOF in read_timeout\n"); } exit_cleanup(1); } @@ -229,7 +238,7 @@ static void readfd(int fd,char *buffer,int N) int ret; int total=0; - if (read_buffer_len < N && N < 1024) { + if ((read_buffer_len < N) && (N < 1024)) { read_check(buffer_f_in); } @@ -310,17 +319,19 @@ static void writefd_unbuffered(int fd,char *buf,int len) int fd_count, count; struct timeval tv; int reading; + int blocked=0; no_flush++; - reading = (buffer_f_in != -1 && read_buffer_len < MAX_READ_BUFFER); - while (total < len) { FD_ZERO(&w_fds); FD_ZERO(&r_fds); FD_SET(fd,&w_fds); fd_count = fd+1; + reading = (buffer_f_in != -1 && + read_buffer_len < MAX_READ_BUFFER); + if (reading) { FD_SET(buffer_f_in,&r_fds); if (buffer_f_in > fd) @@ -340,28 +351,35 @@ static void writefd_unbuffered(int fd,char *buf,int len) continue; } + if (reading && FD_ISSET(buffer_f_in, &r_fds)) { + read_check(buffer_f_in); + } + 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; if (io_timeout) last_io = time(NULL); - continue; - } - - if (reading && FD_ISSET(buffer_f_in, &r_fds)) { - read_check(buffer_f_in); } }