You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Jim Jagielski <ji...@jaguNET.com> on 1997/01/18 03:33:42 UTC

lingering_close questions?

Looking at the lingering_close() code, I see something that
doesn't make sense:

#ifdef HPUX
    while ((select_rv = select (sd + 1, (int*)&fds_read, NULL, (int*)&fds_err,
				&tv)) > 0) {
#else
    while ((select_rv = select (sd + 1, &fds_read, NULL, &fds_err, &tv)) > 0) {
#endif
	if ((read_rv = read (sd, dummybuf, sizeof(dummybuf))) <= 0)
	    break;
	else {
>>>>>>	   fds_read = fds; fds_err = fds;
	}
    }


Why are we resetting fds_read/fds_err?

Also, does it make sense to do the shutdown and the close if
the timer expires (the select returns 0)?
-- 
====================================================================
      Jim Jagielski            |       jaguNET Access Services
     jim@jaguNET.com           |       http://www.jaguNET.com/
                  "Not the Craw... the CRAW!"

Re: lingering_close questions?

Posted by Dean Gaudet <dg...@arctic.org>.
On Fri, 17 Jan 1997, Jim Jagielski wrote:
> >>>>>>	   fds_read = fds; fds_err = fds;
> Why are we resetting fds_read/fds_err?

Well you have to reset them because they are "in out" parameters.  At any
rate, this loop looks bogus to me.  It doesn't check FD_ISSET( sd,
&fds_err ), and it doesn't check FD_ISSET( sd, &fds_read ). 

I don't think select will ever return 0 'cause of the timeout thing.  But
if it is, then the logging code doesn't do the right thing.

Anyone want to try this patch on their server with FIN_WAIT_2s?  (I had to
back out of 1.2 on the hotwired servers 'cause of problems with the
hotwired part of the code.)

Dean

Index: http_main.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_main.c,v
retrieving revision 1.106
diff -u -r1.106 http_main.c
--- http_main.c	1997/01/12 20:38:12	1.106
+++ http_main.c	1997/01/18 21:41:08
@@ -315,7 +315,7 @@
     int dummybuf[512];
     struct timeval tv;
     fd_set fds, fds_read, fds_err;
-    int select_rv = 0, read_rv = 0;
+    int select_rv = 0, read_rv = 0, close_rv;
 
     /* Close our half of the connection --- send client a FIN */
 
@@ -341,24 +341,29 @@
 #else
     while ((select_rv = select (sd + 1, &fds_read, NULL, &fds_err, &tv)) > 0) {
 #endif
-	if ((read_rv = read (sd, dummybuf, sizeof(dummybuf))) <= 0)
+	if( FD_ISSET( sd, &fds_err ) ) {
+	    read_rv = 0;
 	    break;
-	else {
+	} else if ( FD_ISSET( sd, &fds_read )
+	    && (read_rv = read (sd, dummybuf, sizeof(dummybuf))) <= 0) {
+	    break;
+	} else {
 	    fds_read = fds; fds_err = fds;
 	}
     }
 
     /* Log any errors that occured (client closing their end isn't an error) */
-    
+
     if (select_rv < 0)
 	log_unixerr("select", NULL, "lingering_close", server_conf);
-    else if (read_rv < 0 && errno != ECONNRESET)
+    else if (select_rv > 0 && read_rv < 0 && errno != ECONNRESET)
 	log_unixerr("read", NULL, "lingering_close", server_conf);
 
     /* Should now have seen final ack.  Safe to finally kill socket */
 
-    shutdown (sd, 2);
-    close (sd);
+    if ( ( close_rv = close (sd) ) < 0 ) {
+	log_unixerr("close", NULL, "lingering_close", server_conf);
+    }
 }
 #endif