]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[OPTIM] stream_sock_read must check for null-reads more often
authorWilly Tarreau <w@1wt.eu>
Thu, 28 Aug 2008 07:47:43 +0000 (09:47 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 2 Nov 2008 09:19:06 +0000 (10:19 +0100)
With small HTTP messages, stream_sock_read() tends to wake the
task up for a message read without indicating that it may be
the last one. The reason is that level-triggered pollers generally
don't report HUP with data, but only afterwards, so stream_sock_read
has no chance to detect this condition and needs a respin.

So now we return on incomplete buffers only when the buffer is known
as a streamer, because here it generally makes sense. The net result
is that the number of calls in a single HTTP session has dropped
from 5 to 3, with one less wake up and several less calls to
stream_sock_data_update().

src/stream_sock.c

index 3f4be6724d9277729f7db69571350d1d43056481..0b935314a1cec78b039b77033a335836ae78e341 100644 (file)
@@ -180,22 +180,34 @@ int stream_sock_read(int fd) {
                                                //fputc('!', stderr);
                                        }
                                }
+                               /* unfortunately, on level-triggered events, POLL_HUP
+                                * is generally delivered AFTER the system buffer is
+                                * empty, so this one might never match.
+                                */
                                if (fdtab[fd].ev & FD_POLL_HUP)
                                        goto out_shutdown_r;
-                               break;
+
+                               /* if a streamer has read few data, it may be because we
+                                * have exhausted system buffers. It's not worth trying
+                                * again.
+                                */
+                               if (b->flags & BF_STREAMER)
+                                       break;
                        }
 
                        /* generally if we read something smaller than 1 or 2 MSS,
-                        * it means that it's not worth trying to read again. It may
-                        * also happen on headers, but the application then can stop
-                        * reading before we start polling.
+                        * it means that either we have exhausted the system's
+                        * buffers (streamer or question-response protocol) or that
+                        * the connection will be closed. Streamers are easily
+                        * detected so we return early. For other cases, it's still
+                        * better to perform a last read to be sure, because it may
+                        * save one complete poll/read/wakeup cycle in case of shutdown.
                         */
-                       if (ret < MIN_RET_FOR_READ_LOOP)
+                       if (ret < MIN_RET_FOR_READ_LOOP && b->flags & BF_STREAMER)
                                break;
 
                        if (--read_poll <= 0)
                                break;
-
                }
                else if (ret == 0) {
                        /* connection closed */