Hi,

Here's a patch which fixes the FTP half-closed crash I've seen.
It does this:

* exports a commIfHalfClosed(fd) routine..
* .. which I then use in ConnStateData::readSomeData() to
  make 100% sure I'm not reading any data from that fd..
* Started calling AbortChecker::doIOLoop() once a second
  from an event.

The background with this: my FTP connections were being requested
with a Keepalive header and so, even though the read side had
marked the FD as half-closed, the write side completed, discovered
there's a keepalive and then attempted to read some more data.

Comments?




Adrian

Index: client_side.cc
===================================================================
RCS file: /server/cvs-server/squid/squid3/src/client_side.cc,v
retrieving revision 1.668
diff -u -r1.668 client_side.cc
--- client_side.cc      22 Dec 2003 10:28:49 -0000      1.668
+++ client_side.cc      23 Feb 2004 02:46:39 -0000
@@ -197,6 +197,9 @@
 {
     if (reading())
         return;
+    
+    if (commIsHalfClosed(fd))
+           return;
 
     reading(true);
 
Index: comm.cc
===================================================================
RCS file: /server/cvs-server/squid/squid3/src/comm.cc,v
retrieving revision 1.392
diff -u -r1.392 comm.cc
--- comm.cc     18 Feb 2004 01:58:59 -0000      1.392
+++ comm.cc     23 Feb 2004 02:46:40 -0000
@@ -2560,6 +2560,19 @@
     fdc_table[fd].half_closed = true;
 }
 
+int commIsHalfClosed(int fd)
+{
+       assert(fdc_table[fd].active == 1);
+       return fdc_table[fd].half_closed;
+}
+
+void
+commCheckHalfClosed(void *data)
+{
+       AbortChecker::Instance().doIOLoop();
+       eventAdd("commCheckHalfClosed", commCheckHalfClosed, NULL, 1.0, false);
+}
+
 AbortChecker &AbortChecker::Instance() {return Instance_;}
 
 AbortChecker AbortChecker::Instance_;
@@ -2601,22 +2614,8 @@
 #include "splay.h"
 void
 AbortChecker::doIOLoop() {
-    if (checking) {
-        /*
-        fds->walk(RemoveCheck, this);
-        */
-        checking = false;
-        return;
-    }
-
-    if (lastCheck >= squid_curtime)
-        return;
-
+    fds->walk(RemoveCheck, this);
     fds->walk(AddCheck, this);
-
-    checking = true;
-
-    lastCheck = squid_curtime;
 }
 
 void
Index: main.cc
===================================================================
RCS file: /server/cvs-server/squid/squid3/src/main.cc,v
retrieving revision 1.389
diff -u -r1.389 main.cc
--- main.cc     19 Sep 2003 07:06:19 -0000      1.389
+++ main.cc     23 Feb 2004 02:46:40 -0000
@@ -44,6 +44,7 @@
 #include "ACL.h"
 #include "htcp.h"
 #include "StoreFileSystem.h"
+#include "comm.h"
 
 #if USE_WIN32_SERVICE
 
@@ -837,6 +838,7 @@
 #endif
 
         eventAdd("memPoolCleanIdlePools", Mem::CleanIdlePools, NULL, 15.0, 1);
+        eventAdd("commCheckHalfClosed", commCheckHalfClosed, NULL, 1.0, false);
     }
 
     configured_once = 1;
Index: comm.h
===================================================================
RCS file: /server/cvs-server/squid/squid3/src/comm.h,v
retrieving revision 1.20
diff -u -r1.20 comm.h
--- comm.h      15 Aug 2003 13:06:34 -0000      1.20
+++ comm.h      23 Feb 2004 02:46:41 -0000
@@ -30,6 +30,8 @@
 extern void comm_write(int s, const char *buf, size_t len, IOWCB *callback, void 
*callback_data);
 #include "Store.h"
 extern void commMarkHalfClosed(int);
+extern int commIsHalfClosed(int);
+extern void commCheckHalfClosed(void *);
 extern bool comm_has_incomplete_write(int);
 
 /* Where should this belong? */

Reply via email to