---------------------
PatchSet 10844 
Date: 2007/06/10 11:02:23
Author: hno
Branch: HEAD
Tag: (none) 
Log:
Bug #1939: --enable-epoll causes SSL to occationally hang

This patch makes comm_epoll support the "read_pending" flag, indicating
data has been buffered at the I/O layer and is immediately available for
processing without having to wait for an I/O event.

kqueue still needs fixing.

Members: 
	src/comm_epoll.cc:1.15->1.16 
	src/comm_kqueue.cc:1.15->1.16 
	src/comm_poll.cc:1.21->1.22 
	src/comm_select.cc:1.79->1.80 

Index: squid3/src/comm_epoll.cc
===================================================================
RCS file: /cvsroot/squid/squid3/src/comm_epoll.cc,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- squid3/src/comm_epoll.cc	28 Apr 2007 22:26:37 -0000	1.15
+++ squid3/src/comm_epoll.cc	10 Jun 2007 11:02:23 -0000	1.16
@@ -1,6 +1,6 @@
 
 /*
- * $Id: comm_epoll.cc,v 1.15 2007/04/28 22:26:37 hno Exp $
+ * $Id: comm_epoll.cc,v 1.16 2007/06/10 11:02:23 hno Exp $
  *
  * DEBUG: section 5     Socket Functions
  *
@@ -152,8 +152,12 @@
     // If read is an interest
 
     if (type & COMM_SELECT_READ) {
-        if (handler)
+        if (handler) {
+	    // Hack to keep the events flowing if there is data immediately ready
+	    if (F->flags.read_pending)
+		ev.events |= EPOLLOUT;
             ev.events |= EPOLLIN;
+	}
 
         F->read_handler = handler;
 
@@ -281,17 +285,17 @@
 
         // TODO: add EPOLLPRI??
 
-        if (cevents->events & (EPOLLIN|EPOLLHUP|EPOLLERR)) {
+        if (cevents->events & (EPOLLIN|EPOLLHUP|EPOLLERR) || F->flags.read_pending) {
             if ((hdl = F->read_handler) != NULL) {
                 debugs(5, DEBUG_EPOLL ? 0 : 8, "comm_select(): Calling read handler on FD " << fd);
                 PROF_start(comm_write_handler);
+                F->flags.read_pending = 0;
                 F->read_handler = NULL;
                 hdl(fd, F->read_data);
                 PROF_stop(comm_write_handler);
                 statCounter.select_fds++;
             } else {
                 debugs(5, DEBUG_EPOLL ? 0 : 8, "comm_select(): no read handler for FD " << fd);
-                fd_table[fd].flags.read_pending = 1;
                 // remove interest since no handler exist for this event.
                 commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
             }
@@ -306,7 +310,6 @@
                 PROF_stop(comm_read_handler);
                 statCounter.select_fds++;
             } else {
-                fd_table[fd].flags.write_pending = 1;
                 debugs(5, DEBUG_EPOLL ? 0 : 8, "comm_select(): no write handler for FD " << fd);
                 // remove interest since no handler exist for this event.
                 commSetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0);
Index: squid3/src/comm_kqueue.cc
===================================================================
RCS file: /cvsroot/squid/squid3/src/comm_kqueue.cc,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- squid3/src/comm_kqueue.cc	28 Apr 2007 22:26:37 -0000	1.15
+++ squid3/src/comm_kqueue.cc	10 Jun 2007 11:02:23 -0000	1.16
@@ -1,6 +1,6 @@
 
 /*
- * $Id: comm_kqueue.cc,v 1.15 2007/04/28 22:26:37 hno Exp $
+ * $Id: comm_kqueue.cc,v 1.16 2007/06/10 11:02:23 hno Exp $
  *
  * DEBUG: section 5     Socket Functions
  *
@@ -45,6 +45,7 @@
  *
  * - delay pools
  * - deferred reads
+ * - flags.read_pending
  *
  * So, its not entirely useful in a production setup since if a read
  * is meant to be deferred it isn't (we're not even throwing the event
@@ -280,6 +281,7 @@
 
             if ((hdl = F->read_handler) != NULL) {
                 F->read_handler = NULL;
+		F->flags.read_pending = 0;
                 hdl(fd, F->read_data);
             }
 
Index: squid3/src/comm_poll.cc
===================================================================
RCS file: /cvsroot/squid/squid3/src/comm_poll.cc,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- squid3/src/comm_poll.cc	30 Apr 2007 16:56:09 -0000	1.21
+++ squid3/src/comm_poll.cc	10 Jun 2007 11:02:23 -0000	1.22
@@ -1,6 +1,6 @@
 
 /*
- * $Id: comm_poll.cc,v 1.21 2007/04/30 16:56:09 wessels Exp $
+ * $Id: comm_poll.cc,v 1.22 2007/06/10 11:02:23 hno Exp $
  *
  * DEBUG: section 5     Socket Functions
  *
@@ -524,6 +524,7 @@
                 else {
                     PROF_start(comm_read_handler);
                     F->read_handler = NULL;
+		    F->flags.read_pending = 0;
                     hdl(fd, F->read_data);
                     PROF_stop(comm_read_handler);
                     statCounter.select_fds++;
@@ -607,6 +608,7 @@
 
             if ((hdl = F->read_handler)) {
                 F->read_handler = NULL;
+		F->flags.read_pending = 0;
                 hdl(fd, F->read_data);
                 statCounter.select_fds++;
 
Index: squid3/src/comm_select.cc
===================================================================
RCS file: /cvsroot/squid/squid3/src/comm_select.cc,v
retrieving revision 1.79
retrieving revision 1.80
diff -u -r1.79 -r1.80
--- squid3/src/comm_select.cc	30 Apr 2007 16:56:09 -0000	1.79
+++ squid3/src/comm_select.cc	10 Jun 2007 11:02:23 -0000	1.80
@@ -1,6 +1,6 @@
 
 /*
- * $Id: comm_select.cc,v 1.79 2007/04/30 16:56:09 wessels Exp $
+ * $Id: comm_select.cc,v 1.80 2007/06/10 11:02:23 hno Exp $
  *
  * DEBUG: section 5     Socket Functions
  *
@@ -568,6 +568,7 @@
 
                 else {
                     F->read_handler = NULL;
+		    F->flags.read_pending = 0;
                     commUpdateReadBits(fd, NULL);
                     hdl(fd, F->read_data);
                     statCounter.select_fds++;
@@ -663,6 +664,7 @@
 
             if ((hdl = F->read_handler)) {
                 F->read_handler = NULL;
+		F->flags.read_pending = 0;
                 commUpdateReadBits(fd, NULL);
                 hdl(fd, F->read_data);
                 statCounter.select_fds++;
