From: Ralf S. Engelschall Date: Thu, 7 Aug 1997 08:41:46 +0000 (+0000) Subject: Enhanced the chunking and error handling inside the buffer functions. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c18db4e9e55a17620e99fd908521b4f2205b865f;p=thirdparty%2Fapache%2Fhttpd.git 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 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/1.3@78912 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/APACHE_1_2_X/src/CHANGES b/APACHE_1_2_X/src/CHANGES index f33591c5638..39da320f6c2 100644 --- a/APACHE_1_2_X/src/CHANGES +++ b/APACHE_1_2_X/src/CHANGES @@ -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 and 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 diff --git a/APACHE_1_2_X/src/main/buff.c b/APACHE_1_2_X/src/main/buff.c index 97c000272d6..ed448260daf 100644 --- a/APACHE_1_2_X/src/main/buff.c +++ b/APACHE_1_2_X/src/main/buff.c @@ -624,6 +624,7 @@ write_it_all(BUFF *fb, const void *buf, int nbyte) i = write(fb->fd, buf, nbyte); if (i < 0) { if (errno != EAGAIN && errno != EINTR) { + doerror (fb, B_WR); return -1; } } @@ -648,16 +649,28 @@ static int 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 @@ bcwrite(BUFF *fb, const void *buf, int nbyte) * 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 @@ bwrite(BUFF *fb, const void *buf, int nbyte) { /* 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 @@ bwrite(BUFF *fb, const void *buf, int nbyte) /* 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 @@ bwrite(BUFF *fb, const void *buf, int nbyte) */ 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 @@ bflush(BUFF *fb) 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);