]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: listener: don't pause protocols that do not support it
authorWilly Tarreau <w@1wt.eu>
Thu, 4 Oct 2012 06:56:31 +0000 (08:56 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 4 Oct 2012 06:58:21 +0000 (08:58 +0200)
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.

src/listener.c

index f63f9bae3252a7ea8909708154f29075a34ac22b..7c21b9db2ff26efb13f5045a270d9ba66747b5d3 100644 (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;