mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-17 08:54:41 +00:00
MEDIUM: stream-int: clean up the conditions to enable reading in si_conn_wake_cb
The condition to release the SI_FL_WAIT_ROOM flag was abnormally complicated because it was inherited from 6 years ago before we used to check for the buffer's emptiness. The CF_READ_PARTIAL flag had to be removed, and the complex test was replaced with a simpler one checking if *some* data were moved out or not. The reason behind this change is to have a condition compatible with both connections and applets, as applets currently don't work very well in this area. Specifically, some optimizations on the applet side cause them not to release the flag above until the buffer is empty, which may prevent applets from taking together (eg: peers over large haproxy buffers and small kernel buffers).
This commit is contained in:
parent
388a2385a5
commit
ea3cc48d64
@ -573,25 +573,36 @@ static int si_conn_wake_cb(struct connection *conn)
|
||||
si_chk_rcv(si_opposite(si));
|
||||
}
|
||||
|
||||
/* process producer side.
|
||||
* We might have some data the consumer is waiting for.
|
||||
* We can do fast-forwarding, but we avoid doing this for partial
|
||||
* buffers, because it is very likely that it will be done again
|
||||
* immediately afterwards once the following data is parsed (eg:
|
||||
* HTTP chunking).
|
||||
/* Notify the other side when we've injected data into the IC that
|
||||
* needs to be forwarded. We can do fast-forwarding as soon as there
|
||||
* are output data, but we avoid doing this if some of the data are
|
||||
* not yet scheduled for being forwarded, because it is very likely
|
||||
* that it will be done again immediately afterwards once the following
|
||||
* data are parsed (eg: HTTP chunking). We only SI_FL_WAIT_ROOM once
|
||||
* we've emptied *some* of the output buffer, and not just when there
|
||||
* is available room, because applets are often forced to stop before
|
||||
* the buffer is full. We must not stop based on input data alone because
|
||||
* an HTTP parser might need more data to complete the parsing.
|
||||
*/
|
||||
if (((ic->flags & CF_READ_PARTIAL) && !channel_is_empty(ic)) &&
|
||||
(ic->pipe /* always try to send spliced data */ ||
|
||||
(si_ib(si)->i == 0 && (si_opposite(si)->flags & SI_FL_WAIT_DATA)))) {
|
||||
int last_len = ic->pipe ? ic->pipe->data : 0;
|
||||
if (!channel_is_empty(ic) &&
|
||||
(si_opposite(si)->flags & SI_FL_WAIT_DATA) &&
|
||||
(ic->buf->i == 0 || ic->pipe)) {
|
||||
int new_len, last_len;
|
||||
|
||||
last_len = ic->buf->o;
|
||||
if (ic->pipe)
|
||||
last_len += ic->pipe->data;
|
||||
|
||||
si_chk_snd(si_opposite(si));
|
||||
|
||||
new_len = ic->buf->o;
|
||||
if (ic->pipe)
|
||||
new_len += ic->pipe->data;
|
||||
|
||||
/* check if the consumer has freed some space either in the
|
||||
* buffer or in the pipe.
|
||||
*/
|
||||
if (channel_may_recv(ic) &&
|
||||
(!last_len || !ic->pipe || ic->pipe->data < last_len))
|
||||
if (channel_may_recv(ic) && new_len < last_len)
|
||||
si->flags &= ~SI_FL_WAIT_ROOM;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user