mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-23 14:51:27 +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 stream_sock_splice_in(struct buffer *b, struct stream_interface *si)
|
||||||
{
|
{
|
||||||
|
static int splice_detects_close;
|
||||||
int fd = si->fd;
|
int fd = si->fd;
|
||||||
int ret;
|
int ret;
|
||||||
unsigned long max;
|
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) {
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* connection closed. This is only detected by
|
/* 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;
|
b->flags |= BF_READ_NULL;
|
||||||
retval = 1; /* no need for further polling */
|
retval = 1; /* no need for further polling */
|
||||||
break;
|
break;
|
||||||
@ -151,13 +154,18 @@ static int stream_sock_splice_in(struct buffer *b, struct stream_interface *si)
|
|||||||
break;
|
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
|
* 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
|
* try to fall back to the normal recv scheme
|
||||||
* which will be able to deal with the situation.
|
* 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user