From: Willy Tarreau Date: Thu, 4 Oct 2012 06:56:31 +0000 (+0200) Subject: BUG/MEDIUM: listener: don't pause protocols that do not support it X-Git-Tag: v1.5-dev13~228 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b3fb60bdcd15cd3bd925a6423f40498f4a695043;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: listener: don't pause protocols that do not support it Pausing a UNIX_STREAM socket results in a major pain because the socket does not correctly resume, it wakes poll() but return EAGAIN on accept(), resulting in a busy loop. So let's only pause protocols that support it. This issues has existed since UNIX sockets were introduced on bind lines. --- diff --git a/src/listener.c b/src/listener.c index f63f9bae32..7c21b9db2f 100644 --- a/src/listener.c +++ b/src/listener.c @@ -77,14 +77,16 @@ int pause_listener(struct listener *l) if (l->state <= LI_PAUSED) return 1; - if (shutdown(l->fd, SHUT_WR) != 0) - return 0; /* Solaris dies here */ + if (l->proto->sock_prot == IPPROTO_TCP) { + if (shutdown(l->fd, SHUT_WR) != 0) + return 0; /* Solaris dies here */ - if (listen(l->fd, l->backlog ? l->backlog : l->maxconn) != 0) - return 0; /* OpenBSD dies here */ + if (listen(l->fd, l->backlog ? l->backlog : l->maxconn) != 0) + return 0; /* OpenBSD dies here */ - if (shutdown(l->fd, SHUT_RD) != 0) - return 0; /* should always be OK */ + if (shutdown(l->fd, SHUT_RD) != 0) + return 0; /* should always be OK */ + } if (l->state == LI_LIMITED) LIST_DEL(&l->wait_queue); @@ -104,7 +106,8 @@ int resume_listener(struct listener *l) if (l->state < LI_PAUSED) return 0; - if (l->state == LI_PAUSED && + if (l->proto->sock_prot == IPPROTO_TCP && + l->state == LI_PAUSED && listen(l->fd, l->backlog ? l->backlog : l->maxconn) != 0) return 0;