diff options
author | Ying Xue <ying.xue@windriver.com> | 2011-07-06 05:53:15 -0400 |
---|---|---|
committer | Paul Gortmaker <paul.gortmaker@windriver.com> | 2011-09-17 22:55:11 -0400 |
commit | 1d835874af143a5c8273268d09e2f259b4c1ba89 (patch) | |
tree | 207695b37f63f0115225e954617379e92b7027b3 /net | |
parent | 9aa88c2a509e11e6efc466c88b386e0e01bef731 (diff) |
tipc: Add support for SO_SNDTIMEO socket option
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/tipc/socket.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index fc3c281c127d..2f90beba282b 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -525,6 +525,7 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, | |||
525 | struct tipc_port *tport = tipc_sk_port(sk); | 525 | struct tipc_port *tport = tipc_sk_port(sk); |
526 | struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name; | 526 | struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name; |
527 | int needs_conn; | 527 | int needs_conn; |
528 | long timeout_val; | ||
528 | int res = -EINVAL; | 529 | int res = -EINVAL; |
529 | 530 | ||
530 | if (unlikely(!dest)) | 531 | if (unlikely(!dest)) |
@@ -564,6 +565,8 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, | |||
564 | reject_rx_queue(sk); | 565 | reject_rx_queue(sk); |
565 | } | 566 | } |
566 | 567 | ||
568 | timeout_val = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); | ||
569 | |||
567 | do { | 570 | do { |
568 | if (dest->addrtype == TIPC_ADDR_NAME) { | 571 | if (dest->addrtype == TIPC_ADDR_NAME) { |
569 | res = dest_name_check(dest, m); | 572 | res = dest_name_check(dest, m); |
@@ -600,16 +603,14 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, | |||
600 | sock->state = SS_CONNECTING; | 603 | sock->state = SS_CONNECTING; |
601 | break; | 604 | break; |
602 | } | 605 | } |
603 | if (m->msg_flags & MSG_DONTWAIT) { | 606 | if (timeout_val <= 0L) { |
604 | res = -EWOULDBLOCK; | 607 | res = timeout_val ? timeout_val : -EWOULDBLOCK; |
605 | break; | 608 | break; |
606 | } | 609 | } |
607 | release_sock(sk); | 610 | release_sock(sk); |
608 | res = wait_event_interruptible(*sk_sleep(sk), | 611 | timeout_val = wait_event_interruptible_timeout(*sk_sleep(sk), |
609 | !tport->congested); | 612 | !tport->congested, timeout_val); |
610 | lock_sock(sk); | 613 | lock_sock(sk); |
611 | if (res) | ||
612 | break; | ||
613 | } while (1); | 614 | } while (1); |
614 | 615 | ||
615 | exit: | 616 | exit: |
@@ -636,6 +637,7 @@ static int send_packet(struct kiocb *iocb, struct socket *sock, | |||
636 | struct sock *sk = sock->sk; | 637 | struct sock *sk = sock->sk; |
637 | struct tipc_port *tport = tipc_sk_port(sk); | 638 | struct tipc_port *tport = tipc_sk_port(sk); |
638 | struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name; | 639 | struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name; |
640 | long timeout_val; | ||
639 | int res; | 641 | int res; |
640 | 642 | ||
641 | /* Handle implied connection establishment */ | 643 | /* Handle implied connection establishment */ |
@@ -650,6 +652,8 @@ static int send_packet(struct kiocb *iocb, struct socket *sock, | |||
650 | if (iocb) | 652 | if (iocb) |
651 | lock_sock(sk); | 653 | lock_sock(sk); |
652 | 654 | ||
655 | timeout_val = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); | ||
656 | |||
653 | do { | 657 | do { |
654 | if (unlikely(sock->state != SS_CONNECTED)) { | 658 | if (unlikely(sock->state != SS_CONNECTED)) { |
655 | if (sock->state == SS_DISCONNECTING) | 659 | if (sock->state == SS_DISCONNECTING) |
@@ -663,16 +667,14 @@ static int send_packet(struct kiocb *iocb, struct socket *sock, | |||
663 | total_len); | 667 | total_len); |
664 | if (likely(res != -ELINKCONG)) | 668 | if (likely(res != -ELINKCONG)) |
665 | break; | 669 | break; |
666 | if (m->msg_flags & MSG_DONTWAIT) { | 670 | if (timeout_val <= 0L) { |
667 | res = -EWOULDBLOCK; | 671 | res = timeout_val ? timeout_val : -EWOULDBLOCK; |
668 | break; | 672 | break; |
669 | } | 673 | } |
670 | release_sock(sk); | 674 | release_sock(sk); |
671 | res = wait_event_interruptible(*sk_sleep(sk), | 675 | timeout_val = wait_event_interruptible_timeout(*sk_sleep(sk), |
672 | (!tport->congested || !tport->connected)); | 676 | (!tport->congested || !tport->connected), timeout_val); |
673 | lock_sock(sk); | 677 | lock_sock(sk); |
674 | if (res) | ||
675 | break; | ||
676 | } while (1); | 678 | } while (1); |
677 | 679 | ||
678 | if (iocb) | 680 | if (iocb) |