Commit 71092ea122062012f8e4b7fb2f9a747212d1479c

Authored by Allan Stephens
Committed by Paul Gortmaker
1 parent f137917332

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

... ... @@ -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 */