[sheepdog] [PATCH 2/2] net: add a send timeout for sockfd
Liu Yuan
namei.unix at gmail.com
Mon Aug 27 11:32:34 CEST 2012
From: Liu Yuan <tailai.ly at taobao.com>
This fixes the bug found by 035.
This is kind of a subtle case:
'sendmsg' of A would fill its sock buffer to full whlile the other end B is failed
in the middle of the 'sendsmg'. The sock buffer of A is full, then kernel block
the thread awaiting on the buffer drain, which will never happen because B is
down. Keepalive won't be triggered because the kernel detect that sock buffer
has data to send. So the final result is that, the blocked thread will never be
woke up.
Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
include/net.h | 1 +
lib/net.c | 18 ++++++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/include/net.h b/include/net.h
index 4ee0eb6..15ee703 100644
--- a/include/net.h
+++ b/include/net.h
@@ -51,6 +51,7 @@ uint8_t *str_to_addr(int af, const char *ipstr, uint8_t *addr);
int set_nonblocking(int fd);
int set_nodelay(int fd);
int set_keepalive(int fd);
+int set_snd_timeout(int fd);
int set_timeout(int fd);
int get_local_addr(uint8_t *bytes);
diff --git a/lib/net.c b/lib/net.c
index 6ed046a..ef91446 100644
--- a/lib/net.c
+++ b/lib/net.c
@@ -243,6 +243,12 @@ int connect_to(const char *name, int port)
break;
}
+ ret = set_snd_timeout(fd);
+ if (ret) {
+ close(fd);
+ break;
+ }
+
ret = set_nodelay(fd);
if (ret) {
eprintf("%m\n");
@@ -425,6 +431,18 @@ int set_nonblocking(int fd)
return ret;
}
+/* Send timeout for 5 second */
+int set_snd_timeout(int fd)
+{
+ struct timeval timeout;
+
+ timeout.tv_sec = 5;
+ timeout.tv_usec = 0;
+
+ return setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,
+ sizeof(timeout));
+}
+
int set_nodelay(int fd)
{
int ret, opt;
--
1.7.10.2
More information about the sheepdog
mailing list