rse 97/08/07 01:41:48
Modified: src CHANGES buff.c Log: Enhanced the chunking and error handling inside the buffer functions. This also reduces the pause on transfers under certain conditions. Submitted by: Dean Gaudet, Roy Fielding Reviewed by: Dean Gaudet, Roy Fielding, Ralf S. Engelschall Revision Changes Path 1.286.2.42 +4 -0 apache/src/CHANGES Index: CHANGES =================================================================== RCS file: /export/home/cvs/apache/src/CHANGES,v retrieving revision 1.286.2.41 retrieving revision 1.286.2.42 diff -u -r1.286.2.41 -r1.286.2.42 --- CHANGES 1997/08/05 06:49:32 1.286.2.41 +++ CHANGES 1997/08/07 08:41:45 1.286.2.42 @@ -1,5 +1,9 @@ Changes with Apache 1.2.2 + *) Enhanced the chunking and error handling inside the buffer functions. + This also reduces the pause on transfers under certain conditions. + [Dean Gaudet, Roy Fielding] + *) When merging the main server's <Directory> and <Location> sections into a vhost, put the main server's first and the vhost's second. Otherwise the vhost can't override the main server. [Dean Gaudet] PR#717 1.26.2.1 +44 -30 apache/src/buff.c Index: buff.c =================================================================== RCS file: /export/home/cvs/apache/src/buff.c,v retrieving revision 1.26 retrieving revision 1.26.2.1 diff -u -r1.26 -r1.26.2.1 --- buff.c 1997/05/29 05:21:15 1.26 +++ buff.c 1997/08/07 08:41:46 1.26.2.1 @@ -624,6 +624,7 @@ i = write(fb->fd, buf, nbyte); if (i < 0) { if (errno != EAGAIN && errno != EINTR) { + doerror (fb, B_WR); return -1; } } @@ -648,16 +649,28 @@ bcwrite(BUFF *fb, const void *buf, int nbyte) { char chunksize[16]; /* Big enough for practically anything */ + int rv; #ifndef NO_WRITEV struct iovec vec[3]; - int i, rv; + int i; #endif if (fb->flags & (B_WRERR|B_EOUT)) return -1; - if (!(fb->flags & B_CHUNK)) - return write(fb->fd, buf, nbyte); + if (!(fb->flags & B_CHUNK)) { + do rv = write(fb->fd, buf, nbyte); + while (rv == -1 && errno == EINTR && !(fb->flags & B_EOUT)); + if (rv == -1) { + if (errno != EAGAIN) { + doerror (fb, B_WR); + } + return -1; + } else if (rv == 0) { + errno = EAGAIN; + } + return rv; + } #ifdef NO_WRITEV /* without writev() this has poor performance, too bad */ @@ -685,10 +698,15 @@ * to deal with a partial writev() */ for( i = 0; i < NVEC; ) { - do rv = writev( fb->fd, &vec[i], NVEC - i ); - while (rv == -1 && errno == EINTR && !(fb->flags & B_EOUT)); - if (rv == -1) + do { + rv = writev( fb->fd, &vec[i], NVEC - i ); + } while ((rv <= 0) + && !(fb->flags & B_EOUT) + && (errno == EINTR || errno == EAGAIN || rv == 0)); + if (rv == -1) { + doerror (fb, B_WR); return -1; + } /* recalculate vec to deal with partial writes */ while (rv > 0) { if( rv <= vec[i].iov_len ) { @@ -732,15 +750,8 @@ { /* unbuffered write -- have to use bcwrite since we aren't taking care * of chunking any other way */ - do i = bcwrite(fb, buf, nbyte); - while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT)); - if (i == 0) { /* return of 0 means non-blocking */ - errno = EAGAIN; - return -1; - } - else if (i < 0) { - if (errno != EAGAIN) - doerror(fb, B_WR); + i = bcwrite(fb, buf, nbyte); + if (i <= 0) { return -1; } fb->bytes_sent += i; @@ -776,13 +787,17 @@ /* it is just too painful to try to re-cram the buffer while * chunking */ - i = (write_it_all(fb, fb->outbase, fb->outcnt) == -1) ? - -1 : fb->outcnt; - } - else { - do i = write(fb->fd, fb->outbase, fb->outcnt); - while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT)); + if (write_it_all(fb, fb->outbase, fb->outcnt) == -1) { + /* we cannot continue after a chunked error */ + return -1; + } + fb->bytes_sent += fb->outcnt; + fb->outcnt = 0; + break; } + do { + i = write(fb->fd, fb->outbase, fb->outcnt); + } while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT)); if (i <= 0) { if (i == 0) /* return of 0 means non-blocking */ errno = EAGAIN; @@ -815,13 +830,9 @@ */ while (nbyte >= fb->bufsiz) { - do i = bcwrite(fb, buf, nbyte); - while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT)); + i = bcwrite(fb, buf, nbyte); if (i <= 0) { - if (i == 0) /* return of 0 means non-blocking */ - errno = EAGAIN; if (nwr == 0) { - if (errno != EAGAIN) doerror(fb, B_WR); return -1; } else return nwr; @@ -861,12 +872,15 @@ while (fb->outcnt > 0) { - /* the buffer must be full */ - do i = write(fb->fd, fb->outbase, fb->outcnt); - while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT)); + do { + i = write(fb->fd, fb->outbase, fb->outcnt); + } while ((i <= 0) + && !(fb->flags & B_EOUT) + && (errno == EINTR || errno == EAGAIN || i == 0)); + if (i == 0) { errno = EAGAIN; - return -1; /* return of 0 means non-blocking */ + return -1; /* return of 0 means B_EOUT and non-blocking */ } else if (i < 0) { if (errno != EAGAIN) doerror(fb, B_WR);