]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: stream_sock: don't remove BF_EXPECT_MORE and BF_SEND_DONTWAIT on partial...
authorWilly Tarreau <w@1wt.eu>
Fri, 9 Mar 2012 17:10:44 +0000 (18:10 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 9 Mar 2012 17:10:44 +0000 (18:10 +0100)
The flags are one-shot but should be maintained over all send() operations
as long as send_max is not flushed. The flags were incidentely cleared once
a complete send() was performed, regardless of the fact that the send()
might have been on the first half of a buffer before a wrapping. The result
is that on wrapping data (eg: which happens often with chunked encoding),
many incomplete segments are transmitted instead of being aggregated.

The fix consists in only flushing the flags only once send_max is empty,
which was the expected behaviour.

This fix should be backported to 1.4 though it is not critical, just sub-optimal.

src/stream_sock.c

index 29b7fcb2ddca67ef766c88927e8b45b0551273ef..8c9f765e53f7a6653db275df0e32865678fc9848 100644 (file)
@@ -633,10 +633,6 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b)
                                send_flag &= ~MSG_MORE;
 
                        ret = send(si->fd, b->w, max, send_flag);
-
-                       /* Always clear both flags once everything has been sent */
-                       if (ret == max)
-                               b->flags &= ~(BF_EXPECT_MORE | BF_SEND_DONTWAIT);
                } else {
                        int skerr;
                        socklen_t lskerr = sizeof(skerr);
@@ -668,6 +664,8 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b)
 
                        b->send_max -= ret;
                        if (!b->send_max) {
+                               /* Always clear both flags once everything has been sent, they're one-shot */
+                               b->flags &= ~(BF_EXPECT_MORE | BF_SEND_DONTWAIT);
                                if (likely(!b->pipe))
                                        b->flags |= BF_OUT_EMPTY;
                                break;