diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 32 |
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 | |||
61 | static int backlog_rcv(struct sock *sk, struct sk_buff *skb); | 64 | static int backlog_rcv(struct sock *sk, struct sk_buff *skb); |
62 | static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); | 65 | static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); |
63 | static void wakeupdispatch(struct tipc_port *tport); | 66 | static 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); | ||
930 | restart: | 935 | restart: |
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); | |
1058 | restart: | 1062 | restart: |
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 */ |