httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Randy Terbush <ra...@zyzzyva.com>
Subject Re: [PATCH] Handle write errors when no SIGPIPE
Date Sat, 26 Apr 1997 14:22:51 GMT
+1

> In message <199704220637.CAA05677@tripod.tripod.com>, Nathan J Kurz writes:
> >One would think that when you pushed Stop on the browser the script
> >would get a SIGPIPE and die as soon as a buffer was filled and
> >written.  Unfortunately, on Solaris 2.5.1 it doesn't ever get that
> >signal.  Even if you press Stop immediately, until the server Timeout
> >is reached send_fd_length() keeps trying to throw away input as fast
> >as your processor will run:
> >
> >  PID USERNAME PRI NICE  SIZE   RES STATE   TIME   WCPU    CPU COMMAND
> >23864 nate     -25    0 2008K 1680K run     3:27 62.73% 62.73% long_push
> >23797 nate     -15    0 1744K 1304K sleep   1:54 35.22% 35.04% httpd
> >
> >So while Sameer's CGI patch might help in some circumstances, and
> >while this is probably a Solaris bug, and while there probably aren't
> >many CGI's that work like this, it might be worth revisiting the error
> >handling in send_fd_length() when bwrite() returns a -1 and errno is
> >not EAGAIN. :)
> 
> Nathan's comments caused me to revisit the code that I had stared at
> for so long looking for an EPIPE.  I don't know why I missed it the first
> time, but the below patch will fix this problem.  Note that it is needed
> for all systems, since our current code will silently toss data if an
> interim write fails for any reason (very bad).  It will also be a huge
> load reducer for sites sending large messages to impatient users.
> 
> .....Roy
> 
> 
> Index: http_protocol.c
> ===================================================================
> RCS file: /export/home/cvs/apache/src/http_protocol.c,v
> retrieving revision 1.116
> diff -c -r1.116 http_protocol.c
> *** http_protocol.c	1997/04/24 23:35:20	1.116
> --- http_protocol.c	1997/04/26 03:57:38
> ***************
> *** 1540,1553 ****
>           }
>           o=0;
>   	total_bytes_sent += n;
> ! 	
> !         while(n && !r->connection->aborted) {
> !             w=bwrite(r->connection->client, &buf[o], n);
> ! 	    if(w <= 0)
> ! 		break;
> ! 	    reset_timeout(r); /* reset timeout after successful write */
> !             n-=w;
> ! 	    o+=w;
>           }
>       }
>       
> --- 1540,1568 ----
>           }
>           o=0;
>   	total_bytes_sent += n;
> ! 
> !         while (n && !r->connection->aborted) {
> !             w = bwrite(r->connection->client, &buf[o], n);
> !             if (w > 0) {
> !                 reset_timeout(r); /* reset timeout after successful write */
> !                 n-=w;
> !                 o+=w;
> !             }
> !             else if (w < 0) {
> !                 if (r->connection->aborted)
> !                     break;
> !                 else if (errno == EAGAIN || errno == EINTR)
> !                     continue;
> !                 else {
> !                     log_unixerr("send body lost connection to",
> !                                 get_remote_host(r->connection,
> !                                     r->per_dir_config, REMOTE_NAME),
> !                                 NULL, r->server);
> !                     bsetflag(r->connection->client, B_EOUT, 1);
> !                     r->connection->aborted = 1;
> !                     break;
> !                 }
> !             }
>           }
>       }
>       
> Index: buff.c
> ===================================================================
> RCS file: /export/home/cvs/apache/src/buff.c,v
> retrieving revision 1.24
> diff -c -r1.24 buff.c
> *** buff.c	1997/04/21 20:29:07	1.24
> --- buff.c	1997/04/26 03:57:39
> ***************
> *** 99,109 ****
> --- 99,113 ----
>   static void
>   doerror(BUFF *fb, int err)
>   {
> +     int errsave = errno;  /* Save errno to prevent overwriting it below */
> + 
>       if (err == B_RD)
>   	fb->flags |= B_RDERR;
>       else
>   	fb->flags |= B_WRERR;
>       if (fb->error != NULL) (*fb->error)(fb, err, fb->error_data);
> + 
> +     errno = errsave;
>   }
>   
>   /* Buffering routines */




Mime
View raw message