diff options
author | Olaf Kirch <olaf.kirch@oracle.com> | 2007-04-20 22:05:27 -0700 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-04-25 22:29:27 -0700 |
commit | 305f2aa18214555e611ad05e586dd385e64ab665 (patch) | |
tree | 13eb53d462c9a3fc42a30a4571c42f8632249d5d | |
parent | 9958089a43ae8a9af07402461c0b2b7548c7341e (diff) | |
download | linux-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.c | 31 |
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; |