From 7340ca5a54dba6c049f712c181c5a87f72d52760 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sat, 16 Jan 2010 10:03:45 +0100 Subject: [PATCH] [OPTIM] stream_sock: don't shutdown(write) when the socket is in error We get a lot of those, especially with web crawlers : recv(2, 0x810b610, 7000, 0) = -1 ECONNRESET (Connection reset by peer) shutdown(2, 1 /* send */) = -1 ENOTCONN (Transport endpoint is not connected) close(2) = 0 There's no need to perform the shutdown() here, the socket is already in error so it is down. --- src/stream_sock.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/stream_sock.c b/src/stream_sock.c index d84cd1a29..8937c2a56 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -823,7 +823,8 @@ int stream_sock_write(int fd) * This function performs a shutdown-write on a stream interface in a connected or * init state (it does nothing for other states). It either shuts the write side * or closes the file descriptor and marks itself as closed. The buffer flags are - * updated to reflect the new state. + * updated to reflect the new state. It does also close everything is the SI was + * marked as being in error state. */ void stream_sock_shutw(struct stream_interface *si) { @@ -842,7 +843,10 @@ void stream_sock_shutw(struct stream_interface *si) * However, if SI_FL_NOLINGER is explicitly set, we know there is * no risk so we close both sides immediately. */ - if (si->flags & SI_FL_NOLINGER) { + if (si->flags & SI_FL_ERR) { + /* quick close, the socket is already shut. Remove pending flags. */ + si->flags &= ~SI_FL_NOLINGER; + } else if (si->flags & SI_FL_NOLINGER) { si->flags &= ~SI_FL_NOLINGER; setsockopt(si->fd, SOL_SOCKET, SO_LINGER, (struct linger *) &nolinger, sizeof(struct linger));