tipc: Add support for SO_SNDTIMEO socket option
authorYing Xue <ying.xue@windriver.com>
Wed, 6 Jul 2011 09:53:15 +0000 (05:53 -0400)
committerPaul Gortmaker <paul.gortmaker@windriver.com>
Sun, 18 Sep 2011 02:55:11 +0000 (22:55 -0400)
Adds support for the SO_SNDTIMEO socket option. (This complements the
existing support for SO_RCVTIMEO that is already present.)

Signed-off-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Allan Stephens <allan.stephens@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
net/tipc/socket.c

index fc3c281c127d14996b3eeb2f25387053b29f09b7..2f90beba282b193d0878336718e4457ae714b7d9 100644 (file)
@@ -525,6 +525,7 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
        struct tipc_port *tport = tipc_sk_port(sk);
        struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name;
        int needs_conn;
+       long timeout_val;
        int res = -EINVAL;
 
        if (unlikely(!dest))
@@ -564,6 +565,8 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
                reject_rx_queue(sk);
        }
 
+       timeout_val = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
+
        do {
                if (dest->addrtype == TIPC_ADDR_NAME) {
                        res = dest_name_check(dest, m);
@@ -600,16 +603,14 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
                                sock->state = SS_CONNECTING;
                        break;
                }
-               if (m->msg_flags & MSG_DONTWAIT) {
-                       res = -EWOULDBLOCK;
+               if (timeout_val <= 0L) {
+                       res = timeout_val ? timeout_val : -EWOULDBLOCK;
                        break;
                }
                release_sock(sk);
-               res = wait_event_interruptible(*sk_sleep(sk),
-                                              !tport->congested);
+               timeout_val = wait_event_interruptible_timeout(*sk_sleep(sk),
+                                              !tport->congested, timeout_val);
                lock_sock(sk);
-               if (res)
-                       break;
        } while (1);
 
 exit:
@@ -636,6 +637,7 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
        struct sock *sk = sock->sk;
        struct tipc_port *tport = tipc_sk_port(sk);
        struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name;
+       long timeout_val;
        int res;
 
        /* Handle implied connection establishment */
@@ -650,6 +652,8 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
        if (iocb)
                lock_sock(sk);
 
+       timeout_val = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
+
        do {
                if (unlikely(sock->state != SS_CONNECTED)) {
                        if (sock->state == SS_DISCONNECTING)
@@ -663,16 +667,14 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
                                total_len);
                if (likely(res != -ELINKCONG))
                        break;
-               if (m->msg_flags & MSG_DONTWAIT) {
-                       res = -EWOULDBLOCK;
+               if (timeout_val <= 0L) {
+                       res = timeout_val ? timeout_val : -EWOULDBLOCK;
                        break;
                }
                release_sock(sk);
-               res = wait_event_interruptible(*sk_sleep(sk),
-                       (!tport->congested || !tport->connected));
+               timeout_val = wait_event_interruptible_timeout(*sk_sleep(sk),
+                       (!tport->congested || !tport->connected), timeout_val);
                lock_sock(sk);
-               if (res)
-                       break;
        } while (1);
 
        if (iocb)