mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-23 06:41:32 +02:00
OPTIM: stream_sock: save a failed recv syscall when splice returns EAGAIN
When splice() returns EAGAIN, on old kernels it could be caused by a read shutdown which was not detected. Due to this behaviour, we had to fall back to recv(), which in turn says if it's a real EAGAIN or a shutdown. Since this behaviour was fixed in 2.6.27.14, on more recent kernels we'd prefer to avoid the fallback to recv() when possible. For this, we set a variable the first time splice() detects a shutdown, to indicate that it works. We can then rely on this variable to adjust our behaviour. Doing this alone increased the overall performance by about 1% on medium sized objects.
This commit is contained in:
parent
eb9fd5178e
commit
82a04566ec
@ -73,6 +73,7 @@
|
||||
*/
|
||||
static int stream_sock_splice_in(struct buffer *b, struct stream_interface *si)
|
||||
{
|
||||
static int splice_detects_close;
|
||||
int fd = si->fd;
|
||||
int ret;
|
||||
unsigned long max;
|
||||
@ -128,8 +129,10 @@ static int stream_sock_splice_in(struct buffer *b, struct stream_interface *si)
|
||||
if (ret <= 0) {
|
||||
if (ret == 0) {
|
||||
/* connection closed. This is only detected by
|
||||
* recent kernels (>= 2.6.27.13).
|
||||
* recent kernels (>= 2.6.27.13). If we notice
|
||||
* it works, we store the info for later use.
|
||||
*/
|
||||
splice_detects_close = 1;
|
||||
b->flags |= BF_READ_NULL;
|
||||
retval = 1; /* no need for further polling */
|
||||
break;
|
||||
@ -151,13 +154,18 @@ static int stream_sock_splice_in(struct buffer *b, struct stream_interface *si)
|
||||
break;
|
||||
}
|
||||
|
||||
/* We don't know if the connection was closed.
|
||||
/* We don't know if the connection was closed,
|
||||
* but if we know splice detects close, then we
|
||||
* know it for sure.
|
||||
* But if we're called upon POLLIN with an empty
|
||||
* pipe and get EAGAIN, it is suspect enought to
|
||||
* pipe and get EAGAIN, it is suspect enough to
|
||||
* try to fall back to the normal recv scheme
|
||||
* which will be able to deal with the situation.
|
||||
*/
|
||||
retval = -1;
|
||||
if (splice_detects_close)
|
||||
retval = 0; /* we know for sure that it's EAGAIN */
|
||||
else
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user