]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: stream_interface: don't loop over ->snd_buf()
authorWilly Tarreau <w@1wt.eu>
Mon, 29 Oct 2012 22:27:14 +0000 (23:27 +0100)
committerWilly Tarreau <w@1wt.eu>
Mon, 29 Oct 2012 22:30:33 +0000 (23:30 +0100)
It is stupid to loop over ->snd_buf() because the snd_buf() itself already
loops and stops when system buffers are full. But looping again onto it,
we lose the information of the full buffers and perform one useless syscall.

Furthermore, this causes issues when dealing with large uploads while waiting
for a connection to establish, as it can report a server reject of some data
as a connection abort, which is wrong.

1.4 does not have this issue as it loops maximum twice (once for each buffer
half) and exists as soon as system buffers are full. So no backport is needed.

include/common/defaults.h
src/stream_interface.c

index 3a67d3353f1f36068238feb38f0016b4121ae75d..ae49263a18c370ae3d9f51fca72dd3d4c80c8fc4 100644 (file)
 #define MIN_RECV_AT_ONCE_ENOUGH (7*1448)
 #endif
 
-// same, but for writes. Generally, it's enough to write twice: one time for
-// first half of the buffer, and a second time for the last half after a
-// wrap-around.
-#ifndef MAX_WRITE_POLL_LOOPS
-#define MAX_WRITE_POLL_LOOPS 2
-#endif
-
 // The minimum number of bytes to be forwarded that is worth trying to splice.
 // Below 4kB, it's not worth allocating pipes nor pretending to zero-copy.
 #ifndef MIN_SPLICE_FORWARD
index cb3e7ea540f3f43b18bff147cf083c76855f69b9..deb14b4cf8c0e2b521e5b4590e59d052c53a6f84 100644 (file)
@@ -671,7 +671,6 @@ static int si_conn_send_loop(struct connection *conn)
 {
        struct stream_interface *si = conn->owner;
        struct channel *chn = si->ob;
-       int write_poll = MAX_WRITE_POLL_LOOPS;
        int ret;
 
        if (chn->pipe && conn->xprt->snd_pipe) {
@@ -728,8 +727,10 @@ static int si_conn_send_loop(struct connection *conn)
                        break;
                }
 
-               if (--write_poll <= 0)
-                       break;
+               /* if some data remain in the buffer, it's only because the
+                * system bufers are full, so we don't want to loop again.
+                */
+               break;
        } /* while */
 
        if (conn->flags & CO_FL_ERROR)