|
@@ -39,7 +39,6 @@ static struct proto_ops llc_ui_ops;
|
|
|
|
|
|
static int llc_ui_wait_for_conn(struct sock *sk, long timeout);
|
|
static int llc_ui_wait_for_conn(struct sock *sk, long timeout);
|
|
static int llc_ui_wait_for_disc(struct sock *sk, long timeout);
|
|
static int llc_ui_wait_for_disc(struct sock *sk, long timeout);
|
|
-static int llc_ui_wait_for_data(struct sock *sk, long timeout);
|
|
|
|
static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout);
|
|
static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout);
|
|
|
|
|
|
#if 0
|
|
#if 0
|
|
@@ -524,16 +523,19 @@ static int llc_ui_wait_for_conn(struct sock *sk, long timeout)
|
|
return timeout;
|
|
return timeout;
|
|
}
|
|
}
|
|
|
|
|
|
-static int llc_ui_wait_for_data(struct sock *sk, long timeout)
|
|
|
|
|
|
+static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout)
|
|
{
|
|
{
|
|
DEFINE_WAIT(wait);
|
|
DEFINE_WAIT(wait);
|
|
- int rc = 0;
|
|
|
|
|
|
+ struct llc_sock *llc = llc_sk(sk);
|
|
|
|
+ int rc;
|
|
|
|
|
|
while (1) {
|
|
while (1) {
|
|
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
|
|
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
|
|
|
|
+ rc = 0;
|
|
if (sk_wait_event(sk, &timeout,
|
|
if (sk_wait_event(sk, &timeout,
|
|
(sk->sk_shutdown & RCV_SHUTDOWN) ||
|
|
(sk->sk_shutdown & RCV_SHUTDOWN) ||
|
|
- (!skb_queue_empty(&sk->sk_receive_queue))))
|
|
|
|
|
|
+ (!llc_data_accept_state(llc->state) &&
|
|
|
|
+ !llc->p_flag)))
|
|
break;
|
|
break;
|
|
rc = -ERESTARTSYS;
|
|
rc = -ERESTARTSYS;
|
|
if (signal_pending(current))
|
|
if (signal_pending(current))
|
|
@@ -541,34 +543,36 @@ static int llc_ui_wait_for_data(struct sock *sk, long timeout)
|
|
rc = -EAGAIN;
|
|
rc = -EAGAIN;
|
|
if (!timeout)
|
|
if (!timeout)
|
|
break;
|
|
break;
|
|
- rc = 0;
|
|
|
|
}
|
|
}
|
|
finish_wait(sk->sk_sleep, &wait);
|
|
finish_wait(sk->sk_sleep, &wait);
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
|
|
-static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout)
|
|
|
|
|
|
+int llc_wait_data(struct sock *sk, long timeo)
|
|
{
|
|
{
|
|
- DEFINE_WAIT(wait);
|
|
|
|
- struct llc_sock *llc = llc_sk(sk);
|
|
|
|
int rc;
|
|
int rc;
|
|
|
|
|
|
while (1) {
|
|
while (1) {
|
|
- prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
|
|
|
|
|
|
+ /*
|
|
|
|
+ * POSIX 1003.1g mandates this order.
|
|
|
|
+ */
|
|
|
|
+ if (sk->sk_err) {
|
|
|
|
+ rc = sock_error(sk);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
rc = 0;
|
|
rc = 0;
|
|
- if (sk_wait_event(sk, &timeout,
|
|
|
|
- (sk->sk_shutdown & RCV_SHUTDOWN) ||
|
|
|
|
- (!llc_data_accept_state(llc->state) &&
|
|
|
|
- !llc->p_flag)))
|
|
|
|
|
|
+ if (sk->sk_shutdown & RCV_SHUTDOWN)
|
|
break;
|
|
break;
|
|
- rc = -ERESTARTSYS;
|
|
|
|
|
|
+ rc = -EAGAIN;
|
|
|
|
+ if (!timeo)
|
|
|
|
+ break;
|
|
|
|
+ rc = sock_intr_errno(timeo);
|
|
if (signal_pending(current))
|
|
if (signal_pending(current))
|
|
break;
|
|
break;
|
|
- rc = -EAGAIN;
|
|
|
|
- if (!timeout)
|
|
|
|
|
|
+ rc = 0;
|
|
|
|
+ if (sk_wait_data(sk, &timeo))
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- finish_wait(sk->sk_sleep, &wait);
|
|
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -599,7 +603,7 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
|
|
goto out;
|
|
goto out;
|
|
/* wait for a connection to arrive. */
|
|
/* wait for a connection to arrive. */
|
|
if (skb_queue_empty(&sk->sk_receive_queue)) {
|
|
if (skb_queue_empty(&sk->sk_receive_queue)) {
|
|
- rc = llc_ui_wait_for_data(sk, sk->sk_rcvtimeo);
|
|
|
|
|
|
+ rc = llc_wait_data(sk, sk->sk_rcvtimeo);
|
|
if (rc)
|
|
if (rc)
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
@@ -658,7 +662,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|
llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);
|
|
llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);
|
|
lock_sock(sk);
|
|
lock_sock(sk);
|
|
if (skb_queue_empty(&sk->sk_receive_queue)) {
|
|
if (skb_queue_empty(&sk->sk_receive_queue)) {
|
|
- rc = llc_ui_wait_for_data(sk, sock_rcvtimeo(sk, noblock));
|
|
|
|
|
|
+ rc = llc_wait_data(sk, sock_rcvtimeo(sk, noblock));
|
|
if (rc)
|
|
if (rc)
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|