aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Stephens <Allan.Stephens@windriver.com>2011-02-23 14:52:14 -0500
committerPaul Gortmaker <paul.gortmaker@windriver.com>2011-03-13 16:35:16 -0400
commit71092ea122062012f8e4b7fb2f9a747212d1479c (patch)
tree16fe00fb40999810cea58cbe1bcbd0caa3cdabd9
parentf1379173326de4c745c4f610501486e4f3bd9248 (diff)
tipc: Add support for SO_RCVTIMEO socket option
Adds support for the SO_RCVTIMEO socket option to TIPC's socket receive routines. Thanks go out to Raj Hegde <rajenhegde@yahoo.ca> for his contribution to the development and testing this enhancement. Signed-off-by: Allan Stephens <Allan.Stephens@windriver.com> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-rw-r--r--net/tipc/socket.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index d45a294f47e9..29d94d53198d 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -58,6 +58,9 @@ struct tipc_sock {
58#define tipc_sk(sk) ((struct tipc_sock *)(sk)) 58#define tipc_sk(sk) ((struct tipc_sock *)(sk))
59#define tipc_sk_port(sk) ((struct tipc_port *)(tipc_sk(sk)->p)) 59#define tipc_sk_port(sk) ((struct tipc_port *)(tipc_sk(sk)->p))
60 60
61#define tipc_rx_ready(sock) (!skb_queue_empty(&sock->sk->sk_receive_queue) || \
62 (sock->state == SS_DISCONNECTING))
63
61static int backlog_rcv(struct sock *sk, struct sk_buff *skb); 64static int backlog_rcv(struct sock *sk, struct sk_buff *skb);
62static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); 65static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf);
63static void wakeupdispatch(struct tipc_port *tport); 66static void wakeupdispatch(struct tipc_port *tport);
@@ -911,6 +914,7 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
911 struct tipc_port *tport = tipc_sk_port(sk); 914 struct tipc_port *tport = tipc_sk_port(sk);
912 struct sk_buff *buf; 915 struct sk_buff *buf;
913 struct tipc_msg *msg; 916 struct tipc_msg *msg;
917 long timeout;
914 unsigned int sz; 918 unsigned int sz;
915 u32 err; 919 u32 err;
916 int res; 920 int res;
@@ -927,6 +931,7 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
927 goto exit; 931 goto exit;
928 } 932 }
929 933
934 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
930restart: 935restart:
931 936
932 /* Look for a message in receive queue; wait if necessary */ 937 /* Look for a message in receive queue; wait if necessary */
@@ -936,17 +941,15 @@ restart:
936 res = -ENOTCONN; 941 res = -ENOTCONN;
937 goto exit; 942 goto exit;
938 } 943 }
939 if (flags & MSG_DONTWAIT) { 944 if (timeout <= 0L) {
940 res = -EWOULDBLOCK; 945 res = timeout ? timeout : -EWOULDBLOCK;
941 goto exit; 946 goto exit;
942 } 947 }
943 release_sock(sk); 948 release_sock(sk);
944 res = wait_event_interruptible(*sk_sleep(sk), 949 timeout = wait_event_interruptible_timeout(*sk_sleep(sk),
945 (!skb_queue_empty(&sk->sk_receive_queue) || 950 tipc_rx_ready(sock),
946 (sock->state == SS_DISCONNECTING))); 951 timeout);
947 lock_sock(sk); 952 lock_sock(sk);
948 if (res)
949 goto exit;
950 } 953 }
951 954
952 /* Look at first message in receive queue */ 955 /* Look at first message in receive queue */
@@ -1034,6 +1037,7 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1034 struct tipc_port *tport = tipc_sk_port(sk); 1037 struct tipc_port *tport = tipc_sk_port(sk);
1035 struct sk_buff *buf; 1038 struct sk_buff *buf;
1036 struct tipc_msg *msg; 1039 struct tipc_msg *msg;
1040 long timeout;
1037 unsigned int sz; 1041 unsigned int sz;
1038 int sz_to_copy, target, needed; 1042 int sz_to_copy, target, needed;
1039 int sz_copied = 0; 1043 int sz_copied = 0;
@@ -1054,7 +1058,7 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
1054 } 1058 }
1055 1059
1056 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); 1060 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
1057 1061 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
1058restart: 1062restart:
1059 1063
1060 /* Look for a message in receive queue; wait if necessary */ 1064 /* Look for a message in receive queue; wait if necessary */
@@ -1064,17 +1068,15 @@ restart:
1064 res = -ENOTCONN; 1068 res = -ENOTCONN;
1065 goto exit; 1069 goto exit;
1066 } 1070 }
1067 if (flags & MSG_DONTWAIT) { 1071 if (timeout <= 0L) {
1068 res = -EWOULDBLOCK; 1072 res = timeout ? timeout : -EWOULDBLOCK;
1069 goto exit; 1073 goto exit;
1070 } 1074 }
1071 release_sock(sk); 1075 release_sock(sk);
1072 res = wait_event_interruptible(*sk_sleep(sk), 1076 timeout = wait_event_interruptible_timeout(*sk_sleep(sk),
1073 (!skb_queue_empty(&sk->sk_receive_queue) || 1077 tipc_rx_ready(sock),
1074 (sock->state == SS_DISCONNECTING))); 1078 timeout);
1075 lock_sock(sk); 1079 lock_sock(sk);
1076 if (res)
1077 goto exit;
1078 } 1080 }
1079 1081
1080 /* Look at first message in receive queue */ 1082 /* Look at first message in receive queue */