Commit 71092ea122062012f8e4b7fb2f9a747212d1479c
Committed by
Paul Gortmaker
1 parent
f137917332
Exists in
master
and in
40 other branches
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>
Showing 1 changed file with 17 additions and 15 deletions Side-by-side Diff
net/tipc/socket.c
... | ... | @@ -58,6 +58,9 @@ |
58 | 58 | #define tipc_sk(sk) ((struct tipc_sock *)(sk)) |
59 | 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 | + | |
61 | 64 | static int backlog_rcv(struct sock *sk, struct sk_buff *skb); |
62 | 65 | static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); |
63 | 66 | static void wakeupdispatch(struct tipc_port *tport); |
... | ... | @@ -911,6 +914,7 @@ |
911 | 914 | struct tipc_port *tport = tipc_sk_port(sk); |
912 | 915 | struct sk_buff *buf; |
913 | 916 | struct tipc_msg *msg; |
917 | + long timeout; | |
914 | 918 | unsigned int sz; |
915 | 919 | u32 err; |
916 | 920 | int res; |
... | ... | @@ -927,6 +931,7 @@ |
927 | 931 | goto exit; |
928 | 932 | } |
929 | 933 | |
934 | + timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | |
930 | 935 | restart: |
931 | 936 | |
932 | 937 | /* Look for a message in receive queue; wait if necessary */ |
933 | 938 | |
934 | 939 | |
... | ... | @@ -936,17 +941,15 @@ |
936 | 941 | res = -ENOTCONN; |
937 | 942 | goto exit; |
938 | 943 | } |
939 | - if (flags & MSG_DONTWAIT) { | |
940 | - res = -EWOULDBLOCK; | |
944 | + if (timeout <= 0L) { | |
945 | + res = timeout ? timeout : -EWOULDBLOCK; | |
941 | 946 | goto exit; |
942 | 947 | } |
943 | 948 | release_sock(sk); |
944 | - res = wait_event_interruptible(*sk_sleep(sk), | |
945 | - (!skb_queue_empty(&sk->sk_receive_queue) || | |
946 | - (sock->state == SS_DISCONNECTING))); | |
949 | + timeout = wait_event_interruptible_timeout(*sk_sleep(sk), | |
950 | + tipc_rx_ready(sock), | |
951 | + timeout); | |
947 | 952 | lock_sock(sk); |
948 | - if (res) | |
949 | - goto exit; | |
950 | 953 | } |
951 | 954 | |
952 | 955 | /* Look at first message in receive queue */ |
... | ... | @@ -1034,6 +1037,7 @@ |
1034 | 1037 | struct tipc_port *tport = tipc_sk_port(sk); |
1035 | 1038 | struct sk_buff *buf; |
1036 | 1039 | struct tipc_msg *msg; |
1040 | + long timeout; | |
1037 | 1041 | unsigned int sz; |
1038 | 1042 | int sz_to_copy, target, needed; |
1039 | 1043 | int sz_copied = 0; |
... | ... | @@ -1054,7 +1058,7 @@ |
1054 | 1058 | } |
1055 | 1059 | |
1056 | 1060 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); |
1057 | - | |
1061 | + timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | |
1058 | 1062 | restart: |
1059 | 1063 | |
1060 | 1064 | /* Look for a message in receive queue; wait if necessary */ |
1061 | 1065 | |
1062 | 1066 | |
... | ... | @@ -1064,17 +1068,15 @@ |
1064 | 1068 | res = -ENOTCONN; |
1065 | 1069 | goto exit; |
1066 | 1070 | } |
1067 | - if (flags & MSG_DONTWAIT) { | |
1068 | - res = -EWOULDBLOCK; | |
1071 | + if (timeout <= 0L) { | |
1072 | + res = timeout ? timeout : -EWOULDBLOCK; | |
1069 | 1073 | goto exit; |
1070 | 1074 | } |
1071 | 1075 | release_sock(sk); |
1072 | - res = wait_event_interruptible(*sk_sleep(sk), | |
1073 | - (!skb_queue_empty(&sk->sk_receive_queue) || | |
1074 | - (sock->state == SS_DISCONNECTING))); | |
1076 | + timeout = wait_event_interruptible_timeout(*sk_sleep(sk), | |
1077 | + tipc_rx_ready(sock), | |
1078 | + timeout); | |
1075 | 1079 | lock_sock(sk); |
1076 | - if (res) | |
1077 | - goto exit; | |
1078 | 1080 | } |
1079 | 1081 | |
1080 | 1082 | /* Look at first message in receive queue */ |