httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dean Gaudet <dgau...@arctic.org>
Subject Re: [PATCH] for 1.2.X, buff tuning
Date Wed, 06 Aug 1997 09:35:52 GMT
This looks good, and passes my usual buffer tests.  So a +1 on putting it
into 1.2.2.

I called it bhalfduplex() because it's used to check if a stream is really
in a half-duplex mode:  client talks, server talks, client talks, server
talks, ...  I'm open to suggestions.  It's essentially the same as
B_SAFEREAD without actually reading anything.  BTW, B_SAFEREAD is still
necessary because there may be stray CRLFs ready to read ... well, only on
POSTs, but it's a good safety measure. 

Dean

On Wed, 6 Aug 1997, Roy T. Fielding wrote:

> Okay, forget the bflush suggestion for get_remote_host -- I tested it
> using truss and it didn't do what I was expecting anyway.
> 
> The following is Dean's patch without the superfluous start_chunk call
> in bflush, plus a few changes where EAGAIN was not being caught on a
> write that is supposed to be blocking (even if the socket isn't).
> It still needs the porting-backward of the bhalfdup (weird name for that)
> stuff, but I'll leave that to Dean since I need to work on what I am
> supposed to be doing for a while.
> 
> .....Roy
> 
> Index: buff.c
> ===================================================================
> RCS file: /export/home/cvs/apache/src/buff.c,v
> retrieving revision 1.26
> diff -c -r1.26 buff.c
> *** buff.c	1997/05/29 05:21:15	1.26
> --- buff.c	1997/08/06 07:29:51
> ***************
> *** 624,629 ****
> --- 624,630 ----
>   	i = write(fb->fd, buf, nbyte);
>   	if (i < 0) {
>   	    if (errno != EAGAIN && errno != EINTR) {
> + 		doerror (fb, B_WR);
>   		return -1;
>   	    }
>   	}
> ***************
> *** 648,663 ****
>   bcwrite(BUFF *fb, const void *buf, int nbyte)
>   {
>       char chunksize[16];	/* Big enough for practically anything */
>   #ifndef NO_WRITEV
>       struct iovec vec[3];
> !     int i, rv;
>   #endif
>   
>       if (fb->flags & (B_WRERR|B_EOUT))
>   	return -1;
>   
> !     if (!(fb->flags & B_CHUNK))
> ! 	return write(fb->fd, buf, nbyte);
>   
>   #ifdef NO_WRITEV
>       /* without writev() this has poor performance, too bad */
> --- 649,676 ----
>   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;
>   #endif
>   
>       if (fb->flags & (B_WRERR|B_EOUT))
>   	return -1;
>   
> !     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,694 ****
>        * 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)
>   	    return -1;
>   	/* recalculate vec to deal with partial writes */
>   	while (rv > 0) {
>   	    if( rv <= vec[i].iov_len ) {
> --- 698,712 ----
>        * to deal with a partial writev()
>        */
>       for( i = 0; i < NVEC; ) {
> ! 	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,746 ****
>       {
>   /* 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);
>   	    return -1;
>   	}
>   	fb->bytes_sent += i;
> --- 750,757 ----
>       {
>   /* unbuffered write -- have to use bcwrite since we aren't taking care
>    * of chunking any other way */
> ! 	i = bcwrite(fb, buf, nbyte);
> ! 	if (i <= 0) {
>   	    return -1;
>   	}
>   	fb->bytes_sent += i;
> ***************
> *** 776,788 ****
>   	    /* 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 (i <= 0) {
>   	    if (i == 0) /* return of 0 means non-blocking */
>   	        errno = EAGAIN;
> --- 787,803 ----
>   	    /* it is just too painful to try to re-cram the buffer while
>   	     * chunking
>   	     */
> ! 	    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,827 ****
>    */
>       while (nbyte >= fb->bufsiz)
>       {
> ! 	do i = bcwrite(fb, buf, nbyte);
> ! 	while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT));
>   	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;
> --- 830,838 ----
>    */
>       while (nbyte >= fb->bufsiz)
>       {
> ! 	i = bcwrite(fb, buf, nbyte);
>   	if (i <= 0) {
>   	    if (nwr == 0) {
>   		return -1;
>   	    }
>   	    else return nwr;
> ***************
> *** 861,872 ****
>   
>       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));
>   	if (i == 0) {
>   	    errno = EAGAIN;
> ! 	    return -1;  /* return of 0 means non-blocking */
>   	}
>   	else if (i < 0) {
>   	    if (errno != EAGAIN) doerror(fb, B_WR);
> --- 872,886 ----
>   
>       while (fb->outcnt > 0)
>       {
> ! 	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 B_EOUT and non-blocking */
>   	}
>   	else if (i < 0) {
>   	    if (errno != EAGAIN) doerror(fb, B_WR);
> 


Mime
View raw message