summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlaf Kirch <olaf.kirch@oracle.com>2007-04-20 22:05:27 -0700
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-25 22:29:27 -0700
commit305f2aa18214555e611ad05e586dd385e64ab665 (patch)
tree13eb53d462c9a3fc42a30a4571c42f8632249d5d
parent9958089a43ae8a9af07402461c0b2b7548c7341e (diff)
downloadlinux-305f2aa18214555e611ad05e586dd385e64ab665.tar.gz
linux-305f2aa18214555e611ad05e586dd385e64ab665.tar.bz2
linux-305f2aa18214555e611ad05e586dd385e64ab665.zip
[IrDA] af_irda: irda_recvmsg_stream cleanup
This patch cleans up some code in irda_recvmsg_stream, replacing some homebrew code with prepare_to_wait/finish_wait, and by making the code honor sock_rcvtimeo. Signed-off-by: Olaf Kirch <olaf.kirch@oracle.com> Signed-off-by: Samuel Ortiz <samuel@sortiz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/irda/af_irda.c31
1 files changed, 13 insertions, 18 deletions
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index baca1565aa11..a0dbe07a1b19 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -1402,8 +1402,8 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
struct irda_sock *self = irda_sk(sk);
int noblock = flags & MSG_DONTWAIT;
size_t copied = 0;
- int target = 1;
- DECLARE_WAITQUEUE(waitq, current);
+ int target;
+ long timeo;
IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
@@ -1416,8 +1416,8 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
if (flags & MSG_OOB)
return -EOPNOTSUPP;
- if (flags & MSG_WAITALL)
- target = size;
+ target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
+ timeo = sock_rcvtimeo(sk, noblock);
msg->msg_namelen = 0;
@@ -1425,19 +1425,14 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
int chunk;
struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue);
- if (skb==NULL) {
+ if (skb == NULL) {
+ DEFINE_WAIT(wait);
int ret = 0;
if (copied >= target)
break;
- /* The following code is a cut'n'paste of the
- * wait_event_interruptible() macro.
- * We don't us the macro because the test condition
- * is messy. - Jean II */
- set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
- add_wait_queue(sk->sk_sleep, &waitq);
- set_current_state(TASK_INTERRUPTIBLE);
+ prepare_to_wait_exclusive(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
/*
* POSIX 1003.1g mandates this order.
@@ -1450,17 +1445,17 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
else if (noblock)
ret = -EAGAIN;
else if (signal_pending(current))
- ret = -ERESTARTSYS;
+ ret = sock_intr_errno(timeo);
+ else if (sk->sk_state != TCP_ESTABLISHED)
+ ret = -ENOTCONN;
else if (skb_peek(&sk->sk_receive_queue) == NULL)
/* Wait process until data arrives */
schedule();
- current->state = TASK_RUNNING;
- remove_wait_queue(sk->sk_sleep, &waitq);
- clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+ finish_wait(sk->sk_sleep, &wait);
- if(ret)
- return(ret);
+ if (ret)
+ return ret;
if (sk->sk_shutdown & RCV_SHUTDOWN)
break;