[BUG] check: we must not check for error before reading a response
We can receive data with a notification of socket error. But we must not check for the error before reading the data, because it may be an asynchronous error notification that we check too early while the response we're waiting for is available. If there is an error, recv() will get it. This should help with servers that close very fast after the response and should also slightly lower the CPU usage during very fast checks on massive amounts of servers since we eliminate one system call. This should probably be backported to 1.3.
This commit is contained in:
parent
fc1daaf497
commit
a5aa1c86a5
21
src/checks.c
21
src/checks.c
@ -768,19 +768,14 @@ static int event_srv_chk_r(int fd)
|
||||
int len;
|
||||
struct task *t = fdtab[fd].owner;
|
||||
struct server *s = t->context;
|
||||
int skerr;
|
||||
char *desc;
|
||||
socklen_t lskerr = sizeof(skerr);
|
||||
|
||||
len = -1;
|
||||
|
||||
if (unlikely((s->result & SRV_CHK_ERROR) ||
|
||||
(fdtab[fd].state == FD_STERROR) ||
|
||||
(fdtab[fd].ev & FD_POLL_ERR) ||
|
||||
(getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr) == -1) ||
|
||||
(skerr != 0))) {
|
||||
(fdtab[fd].ev & FD_POLL_ERR))) {
|
||||
/* in case of TCP only, this tells us if the connection failed */
|
||||
|
||||
if (!(s->result & SRV_CHK_ERROR))
|
||||
set_server_check_status(s, HCHK_STATUS_SOCKERR, NULL);
|
||||
|
||||
@ -792,10 +787,16 @@ static int event_srv_chk_r(int fd)
|
||||
* works correctly and we don't need to do the getsockopt() on linux.
|
||||
*/
|
||||
len = recv(fd, trash, sizeof(trash), 0);
|
||||
if (unlikely(len < 0 && errno == EAGAIN)) {
|
||||
/* we want some polling to happen first */
|
||||
fdtab[fd].ev &= ~FD_POLL_IN;
|
||||
return 0;
|
||||
if (unlikely(len < 0)) {
|
||||
if (errno == EAGAIN) {
|
||||
/* not ready, we want to poll first */
|
||||
fdtab[fd].ev &= ~FD_POLL_IN;
|
||||
return 0;
|
||||
}
|
||||
/* network error, report it */
|
||||
if (!(s->result & SRV_CHK_ERROR))
|
||||
set_server_check_status(s, HCHK_STATUS_SOCKERR, NULL);
|
||||
goto out_wakeup;
|
||||
}
|
||||
|
||||
if (len < sizeof(trash))
|
||||
|
Loading…
x
Reference in New Issue
Block a user