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.
This commit is contained in:
Willy Tarreau 2012-10-04 08:56:31 +02:00
parent 8113a5d78f
commit b3fb60bdcd

View File

@ -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;